7)Spring事务管理详解 实战笔记

概要:2Spring事务管理接口(隔离级别,传播行为)、3接口介绍、4回滚原理

Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的。对于纯JDBC操作数据库,想要用到事务,可以按照以下步骤进行:

1)获取连接 Connection con = DriverManager.getConnection()

2)开启事务con.setAutoCommit(true/false);

3)执行CRUD        4)提交事务/回滚事务 con.commit() / con.rollback();    5)关闭连接 conn.close();

1.事物的特性(ACID)

原子性、一致性、隔离性、持久性

2.Spring事务管理接口:

PlatformTransactionManager: (平台)事务管理器

TransactionDefinition: 事务定义信息(事务隔离级别、传播行为、超时、只读、回滚规则)

TransactionStatus: 事务运行状态

2.1PlatformTransactionManager:

Spring不直接管理,提供多种事务管理器,委托给Hibernate或JTA等持久化机制,提供相关平台框架事务实现。 通过org.springframework.transaction.PlatformTransactionManager 接口,为各个平台如JDBC、Hibernate等提供事务管理器,实现就是各平台的事

PlatformTransactionManager接口定义了三个方法:

getTransaction :根据指定的传播行为,返回当前活动的事务或创建一个新事务

不同持久层框架所对应的接口实现类:

用JDBC或者iBatis(Mybatis)持久化时,xml配置:

2.2 TransactionDefinition接口:


2.21并发事务带来的问题:(事务隔离级别)

脏读(Dirty read):事务修改,没提交到库,另一个事务访问,用这数据(脏数据:可能不正确)

丢失修改(Lost to modify):事务读时,另一也访该数据,第一个事务改,第二个事务也改。第一个事务丢失

不可重复读(Unrepeatableread):事务内多次读同一数据。事务没结束,另一事务也访问该数据。第一事务中两次读数据之间,第二改事务,导致不一样。 修改时

幻读(Phantom read):与不可重复读类似。事务T1读几行数据,事务T2插入。随后查,T1发现多了不存在的记录,新增或删除时

2.22隔离级别

TransactionDefinition.ISOLATION_DEFAULT:默认隔离级别(用db默认的隔离级别),Mysql 默认REPEATABLE_READ隔离级别 ,Oracle 默认 READ_COMMITTED

1)TransactionDefinition.ISOLATION_READ_UNCOMMITTED:最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读

2)TransactionDefinition.ISOLATION_READ_COMMITTED:允许读取并发事务已经提交的数据,阻止脏读,但幻读或不可重复读仍有可能

3)TransactionDefinition.ISOLATION_REPEATABLE_READ:对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。

4)TransactionDefinition.ISOLATION_SERIALIZABLE:最高隔离级别,防止脏读、不可重复读以及幻读

2.23事务传播行为(解决方法间调用事务问题)

事务方法被另一个事务方法调用时,必须如何传播。如:方法可能继续现有事务中运行,也可开启新事务,并在自的事务中运行。TransactionDefinition定义中传播行为常量:

1)TransactionDefinition.PROPAGATION_REQUIRED:如当前存在事务,则加入该事务;没有创建新事务。

2)TransactionDefinition.PROPAGATION_SUPPORTS:如当前存在事务,则加入该事务;没有,以非事务方式继续运行

3)TransactionDefinition.PROPAGATION_MANDATORY:如当前存在事务,则加入该事务;没有则抛异常

    不支持当前事务的情况:

TransactionDefinition.PROPAGATION_REQUIRES_NEW:创建新事务,当前存在事务,把当前事务挂起

TransactionDefinition.PROPAGATION_NOT_SUPPORTED:非事务方式运行,当前存在事务,把当前事务挂起

TransactionDefinition.PROPAGATION_NEVER:非事务方式运行,当前存在事务,抛异常

    其他情况:

TransactionDefinition.PROPAGATION_NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。

这里需要指出的是,前面的六种事务传播行为是 Spring 从 EJB 中引入的,他们共享相同的概念。而PROPAGATION_NESTED是 Spring 所特有的。以 PROPAGATION_NESTED 启动的事务内嵌于外部事务中(如果存在外部事务的话),此时,内嵌事务并不是一个独立的事务,它依赖于外部事务的存在,只有通过外部的事务提交,才能引起内部事务的提交,嵌套的子事务不能单独提交。如果熟悉 JDBC 中的保存点(SavePoint)的概念,那嵌套事务就很容易理解了,其实嵌套的子事务就是保存点的一个应用,一个事务中可以包括多个保存点,每一个嵌套子事务。另外,外部事务的回滚也会导致嵌套子事务的回滚。

2.24事务超时属性(一个事务允许执行的最长时间)

超时没完成,自动回滚。int表示时间,单位是秒

2.25事务只读属性(对事物资源是否执行只读操作)

以提高事务处理性能。在 TransactionDefinition 中以 boolean 表示

2.26回滚规则(定义事务回滚规则)

定义哪些异常会回滚、哪些不会。默认,运行期异常时会回滚,检查型异常不回滚(与EJB回滚行为一致)

但可声明事务特定检查型异常时,像运行异常那样回滚。还可声明运行异常不回滚

3.TransactionStatus接口介绍

记录事务状态 定义了一组方法,用来获取或判断事务相应状态信息

PlatformTransactionManager.getTransaction(…) 方法返回TransactionStatus 对象。

返回TransactionStatus 对象可能代表新的或已经存在事务(如当前调用堆栈有符合条件事务)。

4、Spring事务回滚底层实现

用TransactionInterceptor方法拦截器实现事务经过以下步骤实现回滚

1)获取事务属性(注解@Transactional的属性)

2)获取事务管理器PlatformTransactionManager

3)获取需要事务的方法名和事务信息

4)创建事务、获取事务

4)目标方法执行

5)事务回滚(如果是嵌套回滚则回滚到保存点)

参考:https://zhuanlan.zhihu.com/p/149409015

另加2:

a方法内调b方法,然后a方法抛出异常导致事务回滚,如何让b方法执行结果不回滚?

B方法事务级别require new,不要写在同一个类aop切不到,想同一个类调用,自己去applicationcontex 拿bean

https://my.oschina.net/xiaolyuh/blog/3109049

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring 事务属性分析 事务管理对于企业应用而言至关重要。它保证了用户的每一次操作都是可靠的,即便出现了异常的...
    壹点零阅读 5,083评论 0 2
  • 很多人喜欢这篇文章,特此同步过来 由浅入深谈论spring事务 前言 这篇其实也要归纳到《常识》系列中,但这重点又...
    码农戏码阅读 10,197评论 2 59
  • 目前JavaWeb系统的框架容器基本都是使用Spring管理的,其中事务管理也是比较重要的,之前也是看过,网上介绍...
    wiliam_wiliam阅读 3,538评论 0 0
  • 事务: 事务是逻辑上的一组操作,要么都执行,要么都不执行。 事物的特性:(ACID) 原子性: 事务是最小的执行单...
    n油炸小朋友阅读 3,157评论 1 1
  • 2018年5月5日 5月5日天玑金服“融到钱,管住钱”大咖分享活动,邀请了撒椒&探鱼品牌管理总公司的财务负责人杨冰...
    Ninahuang阅读 2,726评论 2 1