Location>code7788 >text

Transaction commit events in Spring

Popularity:846 ℃/2024-10-18 16:57:26

What should I do if I want to execute some code at the end of a spring operation transaction?

Why? For example, if we send a message to another system in a transaction, we expect to receive a response from that system a little while after the transaction commits, and then manipulate the data that was just committed. But if the response comes too quickly, like a tornado, our transaction, which is hosted in Spring, may not have committed yet, and we won't be able to manipulate it!

One option is to useApplicationEventPublisherYou can refer to my previous blog on 10 million visitors
/blog/somefuture-2405963

Landed visits are over 1 million, so I'll assume the total visits are 10x that haha

This API was provided with Spring 1, and starting with Spring 5, a new thing-related API was provided calledTransactionSynchronization Mechanisms for synchronizing things.

coding

First write a bean realTransactionSynchronizationconnector

import ;
import ;
import ;

@Component
public class AfterTransactionCommitExecutor implements TransactionSynchronization {

    @Override
    public void afterCommit() {
        // Actions performed after the transaction is committed
        ("Transaction committed, perform subsequent operations"); }
    }

    // Other methods to override...

    public void registerSynchronization() {
        // Register the current instance with the transaction synchronization manager
        (this); // Register the current instance with the transaction synchronization manager.
    }
}

Then, you can call it from the service layer or wherever appropriateregisterSynchronization()method to register the transaction synchronization callback

import ;
import ;
import ;

@Service
public class SomeService {

    @Autowired
    private AfterTransactionCommitExecutor afterTransactionCommitExecutor;

    @Transactional
    public void doWork() {
        // business logic...

        // Registering Transaction Synchronization Callbacks
        ();
    }
}

Basically using it is still about manipulating data, so you need to pass parameters to him.

I Member variables

The easiest thing to do is to add a member attribute.

@Component
public class AfterTransactionCommitExecutor extends TransactionSynchronizationAdapter {

    private Object parameter;

    @Override
    public void afterCommit() {
        // Execute the operation after the transaction commits using the parameter
        doSomethingWithParameter(parameter);
    }

    public void setParameter(Object parameter) {
         = parameter;
    }

    private void doSomethingWithParameter(Object parameter) {
    }

    public void registerSynchronization() {
        (this);
    }
}
@Service
public class SomeService {

    @Autowired
    private AfterTransactionCommitExecutor afterTransactionCommitExecutor;

    @Transactional
    public void doWork(Object parameter) {
        // Setting parameters
        (parameter);
        // Registering Transaction Synchronization Callbacks
        ();
    }
}

II Creating Anonymous Class Objects One at a Time

@Service
public class SomeService {

    @Transactional
    public void doWork(final Object parameter) {
        // business logic...

        // Register the transaction synchronization callback and pass the parameters
        (new TransactionSynchronization() {
            @Override
            public void afterCommit() {
                doSomethingWithParameter(parameter);
            }
        });
    }

    private void doSomethingWithParameter(Object parameter) {
        // Use parameters to perform related operations
    }
}

Note that when using member variables to pass parameters, there may be thread-safety issues if multiple transactions execute concurrently. To avoid this problem, either use ThreadLocal to store the parameters or create a new instance of TransactionSynchronization each time in the transaction method.