Interpret the underlying principles and analyze Spring transaction management

Click on the blue word above to pay attention to the pretty boys and fairies.



1. The basic principle of business


The essence of Spring transaction is actually the support of the database for transactions. Without the transaction support of the database, spring is anThe law provides business functions. For pure JDBC operation database, if you want to use transaction, you can follow the following steps:


  • Get the connection Connection con = DriverManager.getConnection()

  • Open transaction con.setAutoCommit(true/false);

  • Execute CRUD

  • Commit transaction/rollback transaction con.commit() / con.rollback();

  • Close the connection conn.close();


After using Spring's transaction management function, we can no longer write the code of steps 2 and 4, but Spirng will do it automatically. So how does Spring open and close transactions before and after the CRUD we write? To solve this problem, we can understand Spring's transaction management implementation principle as a whole. The following is a brief introduction, the annotation method is an example


  • The configuration file enables annotation-driven, and is identified by the annotation @Transactional on the relevant classes and methods.

  • When spring starts, it will parse and generate related beans. At this time, it will check the classes and methods with related annotations, generate proxies for these classes and methods, and perform related configuration injection according to the relevant parameters of @Transaction, so that in the proxy In the middle, we have dealt with the related transactions (open the normal commit transaction, and abnormally roll back the transaction).

  • The transaction commit and rollback of the real database layer is implemented through binlog or redo log.


Second, the propagation properties of Spring transactions


The so-called propagation property of spring transaction is to define how spring should handle the behavior of these transactions when multiple transactions exist at the same time. These properties are defined in TransactionDefinition, and the explanation of specific constants is shown in the following table:


YOkhPCLwLCiboxLib9pYZGMPicFUicydXEp3JlyvvLBoTfq1nXJCoUZR8icDt5HYsQOXG3RElxSHBXSkND3b36zITSw


3. Database isolation level


YOkhPCLwLCiboxLib9pYZGMPicFUicydXEp3wvMFqC07SDWmRfRAyZt5Zb8jM9UsQ0Dvxl1jbPQRNFa1nA99LGsOoA


Dirty read: A transaction adds, deletes, or modifies data, but it is not committed, and another transaction can read the uncommitted data. If the first transaction rolls back at this time, then the second transaction has read the dirty data.


Non-repeatable read: Two read operations occur in a transaction. Between the first read operation and the second operation, another transaction modifies the data. At this time, the two read data are inconsistent.


Phantom read: The first transaction modifies a certain range of data in batches, and the second transaction adds a piece of data to this range. At this time, the first transaction will lose the modification of the newly added data.


Summarize:


The higher the isolation level, the better the data integrity and consistency can be guaranteed, but the greater the impact on concurrent performance.


The default isolation level of most databases is Read Commited, such as SqlServer, Oracle

The default isolation level of a few databases is: Repeatable Read For example: MySQL InnoDB


Fourth, the isolation level in Spring


YOkhPCLwLCiboxLib9pYZGMPicFUicydXEp3urttnCTHBVzEQala7uPgS3uMv8Xq4AY2MY26ic1nENOC0eJCXDp0vjw


Fifth, the nesting of transactions


Through the foreshadowing of the above theoretical knowledge, we roughly know some properties and characteristics of database transactions and spring transactions. Next, we will deeply understand the mechanism of spring transaction propagation by analyzing some nested transaction scenarios.


Suppose Method A() of outer transaction Service A calls Method B() of inner Service B


PROPAGATION_REQUIRED (spring default)


If the transaction level of ServiceB.methodB() is defined as PROPAGATION_REQUIRED, then spring has already started a transaction when ServiceA.methodA() is executed. At this time, ServiceB.methodB() is called, and ServiceB.methodB() sees that it is already running in ServiceA. Inside the transaction of methodA(), no new transaction is started.


If ServiceB.methodB() finds itself not in a transaction when it runs, it assigns itself a transaction.


This way, if an exception occurs in ServiceA.methodA() or anywhere within ServiceB.methodB(), the transaction will be rolled back.


PROPAGATION_REQUIRES_NEW


比如我们设计 ServiceA.methodA() 的事务级别为 PROPAGATION_REQUIRED,ServiceB.methodB() 的事务级别为 PROPAGATION_REQUIRES_NEW。


那么当执行到 ServiceB.methodB() 的时候,ServiceA.methodA() 所在的事务就会挂起,ServiceB.methodB() 会起一个新的事务,等待 ServiceB.methodB() 的事务完成以后,它才继续执行。


他与 PROPAGATION_REQUIRED 的事务区别在于事务的回滚程度了。因为 ServiceB.methodB() 是新起一个事务,那么就是存在两个不同的事务。如果 ServiceB.methodB() 已经提交,那么 ServiceA.methodA() 失败回滚,ServiceB.methodB() 是不会回滚的。如果 ServiceB.methodB() 失败回滚,如果他抛出的异常被 ServiceA.methodA() 捕获,ServiceA.methodA() 事务仍然可能提交(主要看B抛出的异常是不是A会回滚的异常)。


PROPAGATION_SUPPORTS


假设ServiceB.methodB() 的事务级别为 PROPAGATION_SUPPORTS,那么当执行到ServiceB.methodB()时,如果发现ServiceA.methodA()已经开启了一个事务,则加入当前的事务,如果发现ServiceA.methodA()没有开启事务,则自己也不开启事务。这种时候,内部方法的事务性完全依赖于最外层的事务。


PROPAGATION_NESTED


现在的情况就变得比较复杂了, ServiceB.methodB() 的事务属性被配置为 PROPAGATION_NESTED, 此时两者之间又将如何协作呢? 


ServiceB#methodB 如果 rollback, 那么内部事务(即 ServiceB#methodB) 将回滚到它执行前的 SavePoint 而外部事务(即 ServiceA#methodA) 可以有以下两种处理方式:


a、捕获异常,执行异常分支逻辑

void methodA() {    
        try {    
            ServiceB.methodB();    
        } catch (SomeException) {    
            // 执行其他业务, 如 ServiceC.methodC();    
        }    
    }

这种方式也是嵌套事务最有价值的地方, 它起到了分支执行的效果, 如果 ServiceB.methodB 失败, 那么执行 ServiceC.methodC(), 而 ServiceB.methodB 已经回滚到它执行之前的 SavePoint, 所以不会产生脏数据(相当于此方法从未执行过), 这种特性可以用在某些特殊的业务中, 而 PROPAGATION_REQUIRED 和 PROPAGATION_REQUIRES_NEW 都没有办法做到这一点。


b、 外部事务回滚/提交 代码不做任何修改, 那么如果内部事务(ServiceB#methodB) rollback, 那么首先 ServiceB.methodB 回滚到它执行之前的 SavePoint(在任何情况下都会如此), 外部事务(即 ServiceA#methodA) 将根据具体的配置决定自己是 commit 还是 rollback


另外三种事务传播属性基本用不到,在此不做分析。


六、总结


对于项目中需要使用到事务的地方,我建议开发者还是使用spring的TransactionCallback接口来实现事务,不要盲目使用spring事务注解,如果一定要使用注解,那么一定要对spring事务的传播机制和隔离级别有个详细的了解,否则很可能发生意想不到的效果。





C00FZr2MLREDMZPHG5S8emRsAEunoQdIHSbpWYEAeicJ8AEq1iaS2FaBzgx1NDH5k9qM6ZRlZhEVY5uLcwicxTS0Q


好了今天的分享

就到这咯...


Spring的事物要想深入下去

可还有许多


不过没关系

不用着急

不用担心


因为今晚8:30

动脑学院的Five老师

将会在腾讯课堂

动脑学院

Java高级免费试听课程中


给大家详细讲解

Spring的事物呦


而你只需8:30准点

点击文章最下方

阅读原文即可


或者进入腾讯课堂官网

搜索动脑学院

点击Java免费试听课程进行观看

也可以呦


DZ5OKsovm0u6tGahLiaCNmvbDXrw5Z8iaU8pvscmh2rKibBWXvy3icG0mkaODxZNpibQicQKyhLjmAHHsObFmic1IuzDA


推荐阅读


The cornerstone of high concurrency and distributed systems--the actual combat of database read-write separation

This is the end of learning to program...

On how programmers and product managers get along with each other

How to pretend to be a good programmer

2017 Changsha Internet Online Technology Summit

Invitation from the tribe

Java framework Spring core mechanism

love letter to programmers

The Java senior tribe will give you a free ride of the ofo little yellow car for 60 days, still not coming?

Have you used Cassandra developed by Facebook?

10 Big Data Tools and Frameworks for Java Developers


Recommended micro-signals for programmers 

Java Advanced Tribe

WeChat ID: javagaojibuluo



In the tribe, programmer-related technologies, workplace life, industry hotspot information...and more interesting IT articles and pictures will be shared in this tribe...this.... Only belongs to our programmers.....


 ▼Long press down↓↓↓QR code to identify and follow

DZ5OKsovm0srRNgT4VPYJ2FWuHvujFnXxia6nboPahRFFHH0QzkSdBWXatQkd2MyJvNQ0DLnPr7P2SKmuVibC8dg


Recommended learning materials to obtain WeChat ID 

Long press the QR code below to identify and follow

?


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324644513&siteId=291194637