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