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 useApplicationEventPublisher
You 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 realTransactionSynchronization
connector
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.