This article is participating in “Java Theme Month – Java Debug Notes Event”, see < Event link > for more details.
preface
- To ensure the accuracy of data in Spring. Spring accesses the transactions of the database.
- The nature of transactions is ACID. A=Atomicity; C=Consistency; I=isolation; D=Durability
- Spring implements spring’s transaction propagation properties for the four isolation levels of data. I’m not going to go into details here
Problem description
- Configuring transactions in Spring is also as simple as adding annotations on the launch class and configuring aspects to intercept the methods we define in AOP or simply passing through
Transactional
To implement the transaction configuration. - But in one of my methods I actually found that the transaction was broken.
@Transactional
public ResultInfo getPayInfo(Long id) {
return this.getPaymentInfo(id);
}
Copy the code
- We call another method of the same class, getPaymentInfo, in the getPayInfo method. In both methods we configure transactions that are really two different transactions.
- But when I implemented it, I realized that the end result was not so. The external method getPayInfo transaction is fine. But the transaction inside the this.getPaymentInfo method does not take effect at all. I’m purposely writing errors in this method to get exceptions. However, the data that has been executed is not rolled back. Because external and internal are two different transactions, the external itself does not matter.
- I won’t go into details here about how to configure the difference between external and internal transactions. Is to configure spring’s propagation properties.
Problem analysis
- Problems are good because we have room for improvement. Let’s think about how the transaction is implemented.
- In fact, Spring has no transactions. Spring transactions are really database transactions. Spring is only responsible for forwarding
- Spring implements transactions to ensure that the same database connection is used. This is done with ThreadLocal
- The rest of the connection is managed by the database. Transaction management Spring intercepts aop based. But the code above calls the method through this. We know that beans in Spring are not really objects but rather proxy objects based on native objects.
- Only proxy objects can be intercepted by Spring’s AOP. Whereas this is called directly from within and doesn’t go aop then the transaction here is invalidated.
conclusion
- Transactions rely on AOP. This calls directly sidestep AOP. So there are no transactions.
- You don’t know why. Still need to study hard.