Whenever RunContext chains are nested one should always use RunContexts.coppyCurrent() in order to pass the current ITransaction to the child run context.
This major difference in functionality is not reflected in the implementation code and not obvious in the javadoc.
In particular when using the transaction scope REQUIRES_NEW this difference can have major impacts.
**RunContexts.empty**().withScope(REQUIRES_NEW).run{
// RunContext.CURRENT.get().getTransaction() is null due to RunContexts.empty()
// ITransaction.CURRENT.get() is tx1 since a new ITranscation was created.
// nesting with copyCurrent
**RunContexts.copyCurrent**().withScope(REQUIRED).run{
// all fine, OK
// RunContext.CURRENT.get().getTransaction() is tx1 as set by copyCurrent()
// ITransaction.CURRENT.get() is tx1 since no new ITranscation was created.
}
// nesting with RunContext.copy
**RunContext.CURRENT.get().copy**().withScope(REQUIRED).run{
// NOK
// RunContext.CURRENT.get().getTransaction() is null as set by copy() that uses the parent RunContext.m_transaction that is never set.
// ITransaction.CURRENT.get() is a new transcation tx2 since a new ITranscation had to be created. This is not intuitive and not the expectation of the programmer.
}
}
Improvements
The method RunContext.getTransaction() is only used internally by run context chains and should never be used by user code. --> Add javadoc and @Derecation marker to that method
On the static method RunContexts.copyCurrent and method RunContext.copy() --> Add javadoc to clarifiy the difference regarding transaction and what to use for nesting run context chains.
When using the scope REQUIRES_NEW at build time of a RunContext once the chain with thread locals is applied in TransactionProcessor#runTxRequiresNew add a statement to set the current RunContext m_transaction to the correct value by
RunContext.CURRENT.get().withTransaction(newTransaction)
When nesting multiple RunContext chains the return value of calling
Also the copy algorithm regarding the RunContextm_transaction member is - by design and on purpose - different in
Discrepancy
This major difference in functionality is not reflected in the implementation code and not obvious in the javadoc.
Improvements
The method RunContext.getTransaction() is only used internally by run context chains and should never be used by user code. --> Add javadoc and @Derecation marker to that method
On the static method RunContexts.copyCurrent and method RunContext.copy() --> Add javadoc to clarifiy the difference regarding transaction and what to use for nesting run context chains.
When using the scope REQUIRES_NEW at build time of a RunContext once the chain with thread locals is applied in TransactionProcessor#runTxRequiresNew add a statement to set the current RunContext m_transaction to the correct value by
RunContext.CURRENT.get().withTransaction(newTransaction)