当前位置:网站首页>How to apply @transactional transaction annotation to perfection?

How to apply @transactional transaction annotation to perfection?

2022-07-07 12:45:00 Java collection

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 :

  • 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 .

  • TransactionDefinition.PROPAGATION_REQUIRES_NEW: Create a new transaction , If there are currently transactions , Suspend the current transaction .

  • 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 .

  • 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 .

  • TransactionDefinition.PROPAGATION_MANDATORY: If there are currently transactions , Then join the transaction ; If there is no current transaction , Throw an exception .

  • 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 .

c5d815058ba1a81c95c440f20cbf0293.png

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 :

564b66019905f693a53662c5137ba02f.png

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 !!! in addition , public Number Java selected , reply java interview , Access to interview information .

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

@RestController
public class TransactionalController {
 
    @Autowired
    private TransactionalService transactionalService;
 
    @PostMapping("transactionalTest")
    public void transacionalTest(){
        transactionalService.transactionalMethod();
    }
}

Service Realize the control of transactions in : Interface

public interface TransactionalService {
    void transactionalMethod();
}

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 )

6dd9fec3ea459b245d68865f7a6e33d2.png414a22daccfe9432722836b18ae477a9.png

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 .

a36905438afbbab8a93909cc6fc3b8c4.pngcad262a9edabc98922943a6a3dacc4ab.png

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 .

f748e9a98884fc45528af208b38b92eb.png

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 .

author : Fan Xuebo

https://blog.csdn.net/fanxb92/article/details/81296005

official account “Java selected ” The published content indicates the source of , All rights reserved ( Those whose copyright cannot be verified or whose source is not indicated all come from the Internet , Reprinted , The purpose of reprinting is to convey more information , The copyright belongs to the original author . If there is any infringement , Please contact the , The author will delete the first time !

Many people have asked recently , Is there any readers Communication group ! The way to join is simple , official account Java selected , reply “ Add group ”, You can join the group !

Java Interview questions ( Wechat applet ):3000+ The road test questions , contain Java Basics 、 Concurrent 、JVM、 Threads 、MQ series 、Redis、Spring series 、Elasticsearch、Docker、K8s、Flink、Spark、 Architecture design, etc , Brush questions online at any time !

------ Special recommendation ------

Special recommendation : Focus on the most cutting-edge information and technology sharing , Official account for preparing for overtaking on curves and various open source projects and efficient software ,「 Big coffee notes 」, Focus on finding good things , It's worth your attention . Click the official account card below to follow .

If the article helps , Click to see , Forward! !

原网站

版权声明
本文为[Java collection]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/188/202207071034362156.html