Java面试通关手册(Java学习指南):https://github.com/Snailclimb/Java_Guidejava
微信阅读地址连接:多是最漂亮的Spring事务管理详解git
什么是事务?
事务是逻辑上的一组操做,要么都执行,要么都不执行.github
事物的特性(ACID):
Spring事务管理接口:
所谓事务管理,其实就是“按照给定的事务规则来执行提交或者回滚操做”。面试
PlatformTransactionManager接口介绍
Spring并不直接管理事务,而是提供了多种事务管理器 ,他们将事务管理的职责委托给Hibernate或者JTA等持久化机制所提供的相关平台框架的事务来实现。 Spring事务管理器的接口是: org.springframework.transaction.PlatformTransactionManager ,经过这个接口,Spring为各个平台如JDBC、Hibernate等都提供了对应的事务管理器,可是具体的实现就是各个平台本身的事情了。spring
PlatformTransactionManager接口中定义了三个方法:sql
Public interface PlatformTransactionManager()...{ // Return a currently active transaction or create a new one, according to the specified propagation behavior(根据指定的传播行为,返回当前活动的事务或建立一个新事务。) TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException; // Commit the given transaction, with regard to its status(使用事务目前的状态提交事务) Void commit(TransactionStatus status) throws TransactionException; // Perform a rollback of the given transaction(对执行的事务进行回滚) Void rollback(TransactionStatus status) throws TransactionException; }
咱们刚刚也说了Spring中PlatformTransactionManager根据不一样持久层框架所对应的接口实现类,几个比较常见的以下图所示数据库
好比咱们在使用JDBC或者iBatis(就是Mybatis)进行数据持久化操做时,咱们的xml配置一般以下:编程
<!-- 事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- 数据源 --> <property name="dataSource" ref="dataSource" /> </bean>
TransactionDefinition接口介绍
事务管理器接口 PlatformTransactionManager 经过 getTransaction(TransactionDefinition definition) 方法来获得一个事务,这个方法里面的参数是 TransactionDefinition类 ,这个类就定义了一些基本的事务属性。 后端
那么什么是事务属性呢?微信
事务属性能够理解成事务的一些基本配置,描述了事务策略如何应用到方法上。事务属性包含了5个方面。
TransactionDefinition接口中定义了5个方法以及一些表示事务属性的常量好比隔离级别、传播行为等等的常量。
我下面只是列出了TransactionDefinition接口中的方法而没有给出接口中定义的常量,该接口中的常量信息会在后面依次介绍到。
public interface TransactionDefinition { // 返回事务的传播行为 int getPropagationBehavior(); // 返回事务的隔离级别,事务管理器根据它来控制另一个事务能够看到本事务内的哪些数据 int getIsolationLevel(); // 返回事务必须在多少秒内完成 //返回事务的名字 String getName(); int getTimeout(); // 返回是否优化为只读事务。 boolean isReadOnly(); }
咱们先来看一下 并发事务带来的问题 ,而后再来介绍一下 TransactionDefinition 接口 中定义了五个表示隔离级别的常量。
并发事务带来的问题
在典型的应用程序中,多个事务并发运行,常常会操做相同的数据来完成各自的任务(多个用户对统一数据进行操做)。并发虽然是必须的,但可能会致使一下的问题。
例如:事务1读取某表中的数据A=20,事务2也读取A=20,事务1修改A=A-1,事务2也修改A=A-1,最终结果A=19,事务1的修改被丢失。
不可重复度和幻读区别:
不可重复读的重点是修改,幻读的重点在于新增或者删除。
例1(一样的条件, 你读取过的数据, 再次读取出来发现值不同了 ):事务1中的A先生读取本身的工资为 1000的操做还没完成,事务2中的B先生就修改了A的工资为2000,导 致A再读本身的工资时工资变为 2000;这就是不可重复读。
例2(一样的条件, 第1次和第2次读出来的记录数不同 ):假某工资单表中工资大于3000的有4人,事务1读取了全部工资大于3000的人,共查到4条记录,这时事务2 又插入了一条工资大于3000的记录,事务1再次读取时查到的记录就变为了5条,这样就致使了幻读。
隔离级别
TransactionDefinition 接口中定义了五个表示隔离级别的常量:
是否是感受脑细胞不够用了,桥本奈奈未了解一下~~~颜值逆天好吗!!!
![]()
当事务方法被另外一个事务方法调用时,必须指定事务应该如何传播。例如:方法可能继续在现有事务中运行,也可能开启一个新事务,并在本身的事务中运行。在TransactionDefinition定义中包括了以下几个表示传播行为的常量:
支持当前事务的状况:
不支持当前事务的状况:
其余状况:
这里须要指出的是,前面的六种事务传播行为是 Spring 从 EJB 中引入的,他们共享相同的概念。而 PROPAGATION_NESTED 是 Spring 所特有的。以 PROPAGATION_NESTED 启动的事务内嵌于外部事务中(若是存在外部事务的话),此时,内嵌事务并非一个独立的事务,它依赖于外部事务的存在,只有经过外部的事务提交,才能引发内部事务的提交,嵌套的子事务不能单独提交。若是熟悉 JDBC 中的保存点(SavePoint)的概念,那嵌套事务就很容易理解了,其实嵌套的子事务就是保存点的一个应用,一个事务中能够包括多个保存点,每个嵌套子事务。另外,外部事务的回滚也会致使嵌套子事务的回滚。
所谓事务超时,就是指一个事务所容许执行的最长时间,若是超过该时间限制但事务尚未完成,则自动回滚事务。在 TransactionDefinition 中以 int 的值来表示超时时间,其单位是秒。
事务的只读属性是指,对事务性资源进行只读操做或者是读写操做。所谓事务性资源就是指那些被事务管理的资源,好比数据源、 JMS 资源,以及自定义的事务性资源等等。若是肯定只对事务性资源进行只读操做,那么咱们能够将事务标志为只读的,以提升事务处理的性能。在 TransactionDefinition 中以 boolean 类型来表示该事务是否只读。
这些规则定义了哪些异常会致使事务回滚而哪些不会。默认状况下,事务只有遇到运行期异常时才会回滚,而在遇到检查型异常时不会回滚(这一行为与EJB的回滚行为是一致的)。
可是你能够声明事务在遇到特定的检查型异常时像遇到运行期异常那样回滚。一样,你还能够声明事务遇到特定的异常不回滚,即便这些异常是运行期异常。
TransactionStatus接口介绍
TransactionStatus接口用来记录事务的状态 该接口定义了一组方法,用来获取或判断事务的相应状态信息.
PlatformTransactionManager.getTransaction(…) 方法返回一个 TransactionStatus 对象。返回的TransactionStatus 对象可能表明一个新的或已经存在的事务(若是在当前调用堆栈有一个符合条件的事务)。
TransactionStatus接口接口内容以下:
public interface TransactionStatus{ boolean isNewTransaction(); // 是不是新的事物 boolean hasSavepoint(); // 是否有恢复点 void setRollbackOnly(); // 设置为只回滚 boolean isRollbackOnly(); // 是否为只回滚 boolean isCompleted; // 是否已完成 }
因为篇幅有限,我将在下一篇文章经过转帐实例介绍Spring编程式和声明式事务。
欢迎关注个人微信公众号: "Java面试通关手册" (一个有温度的微信公众号,期待与你共同进步~~~坚持原创,分享美文,分享各类Java学习资源):