TransactionSynchronizationManager
Transaction synchronization manager
TransactionSynchronizationManager
understand
TransactionSynchronizationManager using multiple ThreadLocal maintenance each thread affairs independent resource information, cooperate with AbstractPlatformTransactionManager and its subclasses, Setting thread transaction configuration properties and running state, and can be achieved through the custom TransactionSynchronization register, to monitor the operation of the transaction For the business scenario: Suppose there is an asynchronous operation at the end of the business process, and the business process depends on the transaction, and the asynchronous operation depends on the data that the business process adds or updates in the transaction. The problem is that the asynchronous operation is executed before the transaction is committed, and the data queried is before the transaction is committed. Asynchronous operation is invalid You can use Spring’s custom TransactionSynchronization TransactionSynchronizationManager registration, realize afterCommit method (there are other methods), Enables custom business logic to be executed in that running state of the transaction
TransactionSynchronizationManager
The source code
public abstract class TransactionSynchronizationManager {
// Thread context holds the thread pool object: ConnectionHolder Map object. Threads can obtain the same Connection object through this property.
private static final ThreadLocal<Map<Object, Object>> resources = new NamedThreadLocal<>("Transactional resources");
// Transaction synchronizer, the extension code of the transaction runtime, each thread can register N transaction synchronizers.
private static final ThreadLocal<Set<TransactionSynchronization>> synchronizations = new NamedThreadLocal<>("Transaction synchronizations");
// Transaction name
private static final ThreadLocal<String> currentTransactionName = new NamedThreadLocal<>("Current transaction name");
// Whether the transaction is read-only
private static final ThreadLocal<Boolean> currentTransactionReadOnly = new NamedThreadLocal<>("Current transaction read-only status");
// Transaction isolation level
private static final ThreadLocal<Integer> currentTransactionIsolationLevel = new NamedThreadLocal<>("Current transaction isolation level");
// Whether the transaction is enabled
private static final ThreadLocal<Boolean> actualTransactionActive = new NamedThreadLocal<>("Actual transaction active");
}
Copy the code
In the org. Springframework. Transaction. The interceptor. TransactionInterceptor# invoke, to intercept the transaction method. In createTransactionIfNecessary when performing getTransaction invokes AbstractPlatformTransactionManager# prepareSynchronization synchronizer method to initialize the affairs.
/** * Initialize transaction synchronization as appropriate. */
protected void prepareSynchronization(DefaultTransactionStatus status, TransactionDefinition definition) {
if(status.isNewSynchronization()) { TransactionSynchronizationManager.setActualTransactionActive(status.hasTransaction()); TransactionSynchronizationManager.setCurrentTransactionIsolationLevel( definition.getIsolationLevel() ! = TransactionDefinition.ISOLATION_DEFAULT ? definition.getIsolationLevel() :null); TransactionSynchronizationManager.setCurrentTransactionReadOnly(definition.isReadOnly()); TransactionSynchronizationManager.setCurrentTransactionName(definition.getName()); TransactionSynchronizationManager.initSynchronization(); }}Copy the code
TransactionSynchronization
extension
Generally used is TransactionSynchronization afterCommit and afterCompletion method
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
@Override
public void afterCommit(a) {
// Customize business operations}});Copy the code
Where do afterCommit and afterCompletion trigger?
In AbstractPlatformTransactionManager processCommit method all TransactionSynchronization callback
private void processCommit(DefaultTransactionStatus status) throws TransactionException {
try {
// Commit the transactiondoCommit(status); .try {
// Call back afterCommit methods for all transaction synchronizers.
triggerAfterCommit(status);
}
finally {
// Callback afterCompletion methods for all transaction synchronizers.triggerAfterCompletion(status, TransactionSynchronization.STATUS_COMMITTED); }}finally {
/ / remove TransactionSynchronizationManager ThreadLocal data binding.
// Unbind resources from Thread.
// Set Commit to auto Commit.
// Clean up the ConnectionHolder resource.cleanupAfterCompletion(status); }}Copy the code