-
I am currently implementing a feature that requires a pessimistic // provider.ts - repositories will be injected on this
firstRepo = rootEm.getRepository(First);
secondRepo = rootEm.getRepository(Second);
// service.ts
function getData(id: number, trx?: Transaction) {
return RequestContext.getEntityManager().transactional(async (em: SqlEntityManager) => {
const qb = em.createQueryBuilder(First).setLockMode(LockMode.PESSIMISTIC_WRITE);
return qb.select('*').where({ id }).getResult();
}, trx);
}
function updateSecond(data) {
// Compute something from data...
return this.secondRepo.persistAndFlush(new Second(newData));
}
async function update(id) {
await RequestContext.getEntityManager().transactional(async em => {
const data = await getData(id, em.getTransactionContext()); // Using the provided transaction em
const firstRepo = em.getRepository(First); // Using the provided transaction em
// Compute something from data...
await firstRepo.persist(new First(newData));
await updateSecond(data); // Not using the provided transaction em, so this should not be in the same transaction
await firstRepo.flush(); // This seems to be optional, but I do it just in case
throw new Error(); // Throw to see what is rolled back
});
} When I run the above code, no db updates are done. All queries are ran, but are rolled back. Only one transaction has been started and rolled back, according to the logs. Expected behavior Versions Questions
|
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 7 replies
-
I'd say upgrade to v5, no reason to be worried at this stage as its pretty much done, RC is out :]
That is no longer true, the whole callback is executed in a new transaction scope, so you can use the global EM too and it will pick the right tx context automatically. So you can use the repositories from DI. Note that there is no such thing as "flushing a repository". You always flush the underlying EM, and you always flush the whole unit, not just some entity types. Looking at your example, I dont understand why you expect anything to be persisted. You run things inside transactional block, and at the end you throw. This should never save anything. Nested transactions will be rolled back if the parent tx is. |
Beta Was this translation helpful? Give feedback.
-
That is definitely the plan in the near future :)
It might be useful to mention this in the documentation, since it currently isn't clear and seems to imply that the provided
Because I thought it is required to explicitly pass some kind of a transaction context (either the provided |
Beta Was this translation helpful? Give feedback.
I'd say upgrade to v5, no reason to be worried at this stage as its pretty much done, RC is out :]
That is no longer true, the whole callback is executed in a new transaction scope, so you can use the global EM too and it will pick the right tx context automatically. So you can use the repositories from DI.
Note that there is no such thing as "flushing a repository". You always flush the underlying EM, and you always…