Add TransactionManager.doInNewTransaction
This commit is contained in:
parent
67ae8dac57
commit
02d072a361
@ -6,6 +6,7 @@ import {
|
||||
} from 'typeorm'
|
||||
|
||||
export const ENTITY_MANAGER = 'ENTITY_MANAGER'
|
||||
export const TRANSACTION_ID = 'TRANSACTION_ID'
|
||||
|
||||
export interface ITransactionManager {
|
||||
getEntityManager: () => EntityManager
|
||||
@ -13,6 +14,15 @@ export interface ITransactionManager {
|
||||
target: ObjectType<Entity> | EntitySchema<Entity> | string,
|
||||
) => Repository<Entity>
|
||||
isInTransaction: () => boolean
|
||||
/**
|
||||
* Start a new or reuse an existing transaction.
|
||||
*/
|
||||
doInTransaction: <T>(
|
||||
fn: (entityManager: EntityManager) => Promise<T>) => Promise<T>
|
||||
/**
|
||||
* Always start a new transaction, regardless if there is one already in
|
||||
* progress in the current context.
|
||||
*/
|
||||
doInNewTransaction: <T>(
|
||||
fn: (entityManager: EntityManager) => Promise<T>) => Promise<T>
|
||||
}
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
import {Namespace} from 'cls-hooked'
|
||||
import {ENTITY_MANAGER, ITransactionManager} from './ITransactionManager'
|
||||
import shortid from 'shortid'
|
||||
import {
|
||||
ENTITY_MANAGER, ITransactionManager, TRANSACTION_ID
|
||||
} from './ITransactionManager'
|
||||
import {
|
||||
Connection,
|
||||
EntityManager,
|
||||
@ -34,25 +37,38 @@ export class TransactionManager implements ITransactionManager {
|
||||
return !!this.ns.get(ENTITY_MANAGER)
|
||||
}
|
||||
|
||||
async doInTransaction<T>(fn: (entityManager: EntityManager) => Promise<T>) {
|
||||
async doInTransaction<T>(fn: (em: EntityManager) => Promise<T>) {
|
||||
const alreadyInTransaction = this.isInTransaction()
|
||||
if (alreadyInTransaction) {
|
||||
return await fn(this.getEntityManager())
|
||||
}
|
||||
|
||||
return this.getConnection().manager
|
||||
.transaction(async entityManager => {
|
||||
this.setEntityManager(entityManager)
|
||||
return this.doInNewTransaction(fn)
|
||||
}
|
||||
|
||||
async doInNewTransaction<T>(fn: (em: EntityManager) => Promise<T>) {
|
||||
return this.ns.runAndReturn(async () => {
|
||||
this.setTransactionId(shortid())
|
||||
try {
|
||||
return await fn(entityManager)
|
||||
return await this.getConnection().manager
|
||||
.transaction(async entityManager => {
|
||||
this.setEntityManager(entityManager)
|
||||
try {
|
||||
return await fn(entityManager)
|
||||
} finally {
|
||||
this.setEntityManager(undefined)
|
||||
}
|
||||
})
|
||||
} finally {
|
||||
if (!alreadyInTransaction) {
|
||||
this.setEntityManager(undefined)
|
||||
}
|
||||
this.setTransactionId(undefined)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
protected setTransactionId(transactionId: string | undefined) {
|
||||
this.ns.set(TRANSACTION_ID, transactionId)
|
||||
}
|
||||
|
||||
protected setEntityManager(entityManager: EntityManager | undefined) {
|
||||
this.ns.set(ENTITY_MANAGER, entityManager)
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user