当前位置:网站首页>How to apply @transactional transaction annotation to perfection?
How to apply @transactional transaction annotation to perfection?
2022-07-16 07:48:00 【Dream, wake up】
I was busy at work two days ago , involves @Transactional Control of transactions , He studied it carefully , Quite a gain , It took several days to test and sort out , Just published today , Hope to see the old iron bloggers get something . Don't talk too much, go straight to the point .
Just a quick introduction Spring The spread of transactions :
The so-called communication of affairs refers to , If before starting the current transaction , A transaction context already exists , There are several options to specify the execution behavior of a transactional method . stay TransactionDefinition Several constants representing propagation behavior are included in the definition :
1、TransactionDefinition.PROPAGATION_REQUIRED: If there are currently transactions , Then join the transaction ; If there is no current transaction , Create a new transaction . This is the default .
2、’TransactionDefinition.PROPAGATION_REQUIRES_NEW: Create a new transaction , If there are currently transactions , Suspend the current transaction .
3、TransactionDefinition.PROPAGATION_SUPPORTS: If there are currently transactions , Then join the transaction ; If there is no current transaction , Continue to run in a non transactional manner .
4、TransactionDefinition.PROPAGATION_NOT_SUPPORTED: Run in a non transactional manner , If there are currently transactions , Suspend the current transaction .
TransactionDefinition.PROPAGATION_NEVER: Run in a non transactional manner , If there are currently transactions , Throw an exception .
5、TransactionDefinition.PROPAGATION_MANDATORY: If there are currently transactions , Then join the transaction ; If there is no current transaction , Throw an exception .
6、TransactionDefinition.PROPAGATION_NESTED: If there are currently transactions , Create a transaction to run as a nested transaction of the current transaction ; If there is no current transaction , Then the value is equivalent to TransactionDefinition.PROPAGATION_REQUIRED.
And then say Spring Transaction rollback mechanism :
Spring Of AOP That is, declarative transaction management is for by default unchecked exception Roll back .Spring The transaction boundary starts before calling the business method , After the execution of the business method, execute commit or rollback(Spring The default depends on whether to throw runtimeException).
If you have try{}catch(Exception e){} Handle , that try The code block inside is separated from transaction management , In order for the transaction to take effect, it needs to be in catch in throw new RuntimeException (“xxxxxx”); This is also the scenario of failure of affairs that will be asked in the interview .
Let me give you a brief introduction @Transactional Annotate the underlying implementation , without doubt , It's through dynamic proxy , Then dynamic agents are divided into JDK Self and CGLIB, I won't repeat this much , After all, today's theme is how to @Transactional The control of things is applied to perfection . ha-ha ~
The first thing to note is that @Transactional In the method of annotation , Then call other methods in this class method2 when , that method2 Method @Transactional Annotation is not ! Meeting ! raw ! effect ! Of ! But plus, it won't report an error , Take pictures to help you understand . This is also the scenario of failure of affairs that will be asked in the interview .

Method enhancement before and after the target object through the proxy object , That is, transaction initiation, commit and rollback . So what about continuing to call other methods in this class , Here's the picture :
It can be seen that the self call inside the target object , That is, through this. The target object pointed to will not perform the enhancement of the method .
Let's start with the second point that needs attention , Let's talk about how to solve the problem of the first point above . The second point is @Transactional The method of annotation must be a public method , It has to be public Modifier !!!
As for the reason for this , Express your personal understanding , because JVM The dynamic agent is implemented based on the interface , The target method is enhanced through the proxy class , Think about it, too , No access, so what do you want me to do ,,, ok , I didn't go deep into this , Personal understanding personal understanding .
Let me also put a question here , I hope some experts can reply and instruct me , because JVM Dynamic proxies are implemented based on interfaces , So is it service All layers should follow the development mode of interface and implementation class , The annotation will take effect , That is to say controller The layer directly calls the without interface service layer , It doesn't work with annotations , This is lazy , No test , One is because no one will develop it like this , Second, I think it doesn't work , ha-ha
Let's solve the first problem , How to call other methods in this class in a method .
adopt AopContext.currentProxy () Get the proxy object of this class , Just call again . Because this is CGLIB Realization , So turn on AOP, It's also very simple , stay springboot Annotate the startup class @EnableAspectJAutoProxy(exposeProxy = true) That's all right. , It depends on you to search it by yourself . it is to be noted that , Be careful , The method called by the proxy object should also be public Modifier , Otherwise, the injected... Cannot be obtained in the method bean, A null pointer error will be reported .
emmmm, Let me talk about the method and result of the call first . I simply wrote the code myself , It's a little rough , Don't mind , Hey ...
Controller Call in Service
Service Realize the control of transactions in : Interface 
Service Realize the control of transactions in : Implementation class ( Descriptions of various situations are written in the picture , It's easy to read , Help you understand quickly )


In the above two cases, the method is called without proxy 1 And methods 2, Method transactionalMethod All in one transaction , All four update operations failed .
Then someone may have questions , In the method 1 And methods 2 Plus all @Transactional What about the notes ? The answer is that the result is consistent with the above .
Summary as long as the method transactionalMethod There's a note on it , And the way 1 And methods 2 Are in the current transaction ( Do not use proxy to call , Method 1 And methods 2 Upper @Transactional Annotations are not valid ; Using agents , Need method 1 And methods 2 All in transactionalMethod Method , Either default or nested transactions , Of course, it can be omitted @Transactional annotation ), So keep transaction consistency as a whole .
If you want a way 1 And methods 2 How to keep the transaction consistency separately , I just said , If you don't call with a proxy @Transactional Annotations are not valid , So be sure to use proxy calls to implement , Then let the method 1 And methods 2 Open new transactions separately , then OK La . Put the picture below .


Both cases are methods 1 And methods 2 Are in separate transactions , Keep the consistency of transactions .
Next, further optimization , Can be in transactionalMethod In the method, the method 1 And methods 2 Control . The art of code should be brought into full play , Let's start .

The code is too long , Beyond the screen , Paste out the screenshot , The red box notes need to be read carefully , I hope it doesn't affect your reading experience , thus , This article is about @Transactioinal That's all for annotations ,
Let's summarize briefly :
1、 Namely @Transactional Annotations ensure that each method is in a transaction , If there is try It must be catch Throw a runtime exception in .
2、 The method must be public Modifier . Otherwise the annotation will not take effect , But there's nothing wrong with adding notes , No mistake. , It's just useless .
3、this. The call of this method , The annotation on the called method does not take effect , Because the slice enhancement cannot be performed again .
If there is more detailed discussion, please comment , Thank you for reading .
边栏推荐
- 都说软件测试有手就行,每个人都能做,但为何每年仍有大批被劝退的?
- Detailed explanation of sliding window
- In 2 years, the salary increased by 20K, and the transformation from outsourcing manual to test manager
- 0 1背包 填表实现
- 为什么都说测试岗位是巨坑?10年测试人告诉你千万别上当~
- 主从复制读写分离保姆级教学
- appium中desired_caps参数记录
- 如何将 @Transactional 事务注解运用到炉火纯青?
- 從功能測試到自動化測試,實現薪資翻倍,我整理的超全學習指南【附學習筆記】
- Is it reliable to switch to software testing at the age of 30? The mental journey of a person who came here is for you who are confused
猜你喜欢

为什么都说测试岗位是巨坑?10年测试人告诉你千万别上当~

“挤破脑袋进的腾讯,你凭什么要辞职?”

RAID磁盘阵列

It is said that software testing can be done by everyone, but why are there still a large number of people who are discouraged every year?

Redis master-slave cluster construction and sentinel mode configuration

Set up in Jenkins to show the summary of allure Report

01 knapsack filling form implementation

主从复制读写分离保姆级教学

如何将 @Transactional 事务注解运用到炉火纯青?

基于SonarQube代码质量检查
随机推荐
Detailed explanation of sliding window
Network cabling overview
Pytest系列-01-安装与入门
Network layer protocol
还在用策略模式解决 if-else?Map+函数式接口方法才是YYDS
如何将 @Transactional 事务注解运用到炉火纯青?
都说软件测试有手就行,每个人都能做,但为何每年仍有大批被劝退的?
静态路由的原理和配置
2个用例之间存在关联,怎么解?
"Finally I left bytek..." confession of a test engineer with an annual salary of 40W
As an interviewer for the test development post, how do I choose people?
RAID磁盘阵列
Socket details
Jenkins中设置展示Allure报告小结
向“钱”看~毕业两年,年薪30W的测试员的经历...
Why is it said that the testing post is a giant pit? The 10-year-old tester told you not to be fooled~
【LeetCode】380. O (1) time insertion, deletion and acquisition of random elements
丑数
数制转换与子网划分
appium中desired_caps参数记录