Skip to content

Commit

Permalink
replace executeIsolated with PrismaTransactional.prismaRoot
Browse files Browse the repository at this point in the history
  • Loading branch information
myfunc committed Jun 27, 2024
1 parent 3ca2b5b commit 3cffed1
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 20 deletions.
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,11 @@ Execute a query out of current transaction context.
const { balance } = await this.getBalance(userId);

// userLog item will be created even if current transaction will be rolled back.
await PrismaTransactional.executeIsolated(async (rootClient: PrismaClient) => {
await rootClient.userLog.create({ note: `Attempt to add balance for user ${userId} with balance ${balance}`});
});
await PrismaTransactional.prismaRoot.userLog.create(
{
note: `Attempt to add balance for user ${userId} with balance ${balance}`
}
);

const newBalance = await this.prisma.user.update({
select: {
Expand All @@ -147,7 +149,7 @@ Execute a query out of current transaction context.

## Plans

- [x] Add `PrismaTransactional.executeIsolated` method for running queries out of transaction context.
- [x] Add `PrismaTransactional.prismaRoot` method for running queries out of transaction context.
- [ ] Add tests.
- [x] Add express.js example.
- [ ] Add nestjs example.
Expand Down
6 changes: 3 additions & 3 deletions examples/express/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,11 @@ class PostService {
console.log('txCreate30PostsAndThrow PrismaTransactional.onSuccess');
});
await this.postRepository.createPost({ title: 'Not existing post' });
await PrismaTransactional.executeIsolated(async (client: PrismaClient) => {
await client.post.create({ data: { title: 'Isolated post' } });
});
await PrismaTransactional.prismaRoot.post.create({ data: { title: 'Isolated post' } });
await WaitAsync(100);

PrismaTransactional;

this.throwError();
}

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@myfunc/prisma-transactional",
"version": "0.2.0",
"version": "0.3.0",
"author": "myfunc",
"description": "Decorator that wraps all prisma queries along the whole call stack to a single transaction.",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion src/core.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Prisma, PrismaClient } from '@prisma/client/extension';
import { Prisma, PrismaClient } from '@prisma/client';
import { ClsService, ClsServiceManager } from 'nestjs-cls';
import { TX_CLIENT_KEY, TX_CLIENT_SUCCESS_CALLBACKS } from './const';
import { Manager } from './manager';
Expand Down
19 changes: 9 additions & 10 deletions src/decorator.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PrismaClient } from '@prisma/client/extension';
import { PrismaClient } from '@prisma/client';
import { ClsService, ClsServiceManager } from 'nestjs-cls';
import { TX_CLIENT_KEY, TRANSACTION_TIMEOUT, TX_CLIENT_SUCCESS_CALLBACKS } from './const';
import { Manager } from './manager';
Expand All @@ -25,7 +25,7 @@ export function PrismaTransactional(isolationLevel?: string): MethodDecorator {
}

// Utility to manage success callback queue
PrismaTransactional.onSuccess = (callback: () => void | Promise<void>) => {
PrismaTransactional.onSuccess = <T>(callback: () => T | Promise<T>): T | Promise<T> | undefined => {
const clsService = ClsServiceManager.getClsService();
const isActiveTransaction = clsService.get(TX_CLIENT_KEY);

Expand Down Expand Up @@ -58,11 +58,10 @@ PrismaTransactional.execute = <T>(
}
};

// Run callback with isolated PrismaClient with no transaction.
// Only for parameter prismaClient, if other client will be used it will be executed in transaction if exists
PrismaTransactional.executeIsolated = <T>(
callback: (prismaClient: PrismaClient) => Promise<T>,
): Promise<T> => {
const prismaRoot = Manager.prismaClient['$root'] as PrismaClient;
return callback(prismaRoot);
};
PrismaTransactional.prismaRoot = null as unknown as PrismaClient;
// Run query with no transaction even if it exists.
Object.defineProperty(PrismaTransactional, 'prismaRoot', {
get(): PrismaClient {
return Manager.prismaClient['$root'] as PrismaClient;
},
});
2 changes: 1 addition & 1 deletion src/manager.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PrismaClient } from '@prisma/client/extension';
import { PrismaClient } from '@prisma/client';
import { ILoggerService, PrismaTransactionalConfig } from './type';
import { ConsoleLogger } from './logger/console-logger';
import { EmptyLogger } from './logger/empty-logger';
Expand Down

0 comments on commit 3cffed1

Please sign in to comment.