-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(be): implement transaction rollback in unit test (#1562)
* feat(be): implement transaction extension for prisma client prisma/prisma-client-extensions#47 참고하여 작성했습니다 * feat(be): add transaction extension on index ts file * feat(be): implement transaction rollback for group service unit test * test(be): add comments and type * test(be): add await keyword * test(be): add chai exclude * test(be): delete override prisma service func * test(be): increase timeout for before each hook * test(be): disable timeout for before each hook * test(be): add comment * test(be): fix comment
- Loading branch information
Showing
3 changed files
with
93 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
export * from './prisma.module' | ||
export * from './prisma.service' | ||
export * from './transaction.extension' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import { Prisma } from '@prisma/client' | ||
import { PrismaService } from './prisma.service' | ||
|
||
export type FlatTransactionClient = Prisma.TransactionClient & { | ||
$commit: () => Promise<void> | ||
$rollback: () => Promise<void> | ||
} | ||
|
||
const ROLLBACK = { [Symbol.for('prisma.client.extension.rollback')]: true } | ||
|
||
export const transactionExtension = Prisma.defineExtension({ | ||
client: { | ||
async $begin() { | ||
const prisma = Prisma.getExtensionContext(this) | ||
let setTxClient: (txClient: Prisma.TransactionClient) => void | ||
let commit: () => void | ||
let rollback: () => void | ||
|
||
// a promise for getting the tx inner client | ||
const txClient = new Promise<Prisma.TransactionClient>((res) => { | ||
setTxClient = res | ||
}) | ||
|
||
// a promise for controlling the transaction | ||
const txPromise = new Promise((_res, _rej) => { | ||
commit = () => _res(undefined) | ||
rollback = () => _rej(ROLLBACK) | ||
}) | ||
|
||
// opening a transaction to control externally | ||
if ( | ||
'$transaction' in prisma && | ||
typeof prisma.$transaction === 'function' | ||
) { | ||
const tx = prisma | ||
.$transaction((txClient) => { | ||
setTxClient(txClient as unknown as Prisma.TransactionClient) | ||
return txPromise | ||
}) | ||
.catch((e) => { | ||
if (e === ROLLBACK) { | ||
return | ||
} | ||
throw e | ||
}) | ||
|
||
// return a proxy TransactionClient with `$commit` and `$rollback` methods | ||
return new Proxy(await txClient, { | ||
get(target, prop) { | ||
if (prop === '$commit') { | ||
return () => { | ||
commit() | ||
return tx | ||
} | ||
} | ||
if (prop === '$rollback') { | ||
return () => { | ||
rollback() | ||
return tx | ||
} | ||
} | ||
return target[prop as keyof typeof target] | ||
} | ||
}) as FlatTransactionClient | ||
} | ||
|
||
throw new Error('Transactions are not supported by this client') | ||
}, | ||
getPaginator: PrismaService.prototype.getPaginator | ||
} | ||
}) |