首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

spring事务配置及用法

spring事务配置及用法

spring事务

在spring事务出现之前,基本都是在代码中获取数据库连接、开启事务、CRUD操作、 事务提交或回滚、关闭连接,所有的CRUD操作按照这样的流程封装成模板使用,核心代码大致如下:

传统的jdbc事务控制代码与业务逻辑代码耦合性高,开发人员需要手工控制事务和业务代码开发,效率低并且风险高,而使用spring之后,开发人员无需去关注获取数据库连接、开启事务、 事务提交或回滚、关闭连接这样的操作,把更多的时间和精力放在业务逻辑处理上。

实际spring并不直接管理事务,而是提供了多种事务管理器,提供各数据库统一的接口,将事务管理的职责委托给Hibernate或者JTA等持久化机制所提供的相关平台框架的事务来实现。

spring事务的特性如下图所示

spring事务核心接口

由此可以看到PlatformTransactionManager这个类作为事务管理器的核心接口,只提供获取事务、提交事务、回滚事务的接口,支持事务的框架需要实现这些接口。

TransactionDefinition接口中定义了事务传播行为和隔离级别的常量和获取方法

以上就是事务管理的核心接口类,具体的实现需要hibernate、jta等持久化框架实现,不过spring已经支持了对这些框架的整合,通过简单的事务配置即可完成事务管理,并且spring自身提供了jdbc事务的管理。

spring提供的常用内置事务管理器

DataSourceTransactionManager:位于org.springframework.jdbc.datasource包中,数据源事务管理器,提供对单个javax.sql.DataSource事务管理,用于Spring JDBC抽象框架、iBATIS或MyBatis框架的事务管理。

JdoTransactionManager:位于org.springframework.orm.jdo包中,提供对单个javax.jdo.PersistenceManagerFactory事务管理,用于集成JDO框架时的事务管理。

JpaTransactionManager:位于org.springframework.orm.jpa包中,提供对单个javax.persistence.EntityManagerFactory事务支持,用于集成JPA实现框架时的事务管理。

HibernateTransactionManager:位于org.springframework.orm.hibernate3包中,提供对单个org.hibernate.SessionFactory事务支持,用于集成Hibernate框架时的事务管理;该事务管理器只支持Hibernate3+版本,且Spring3.0+版本只支持Hibernate3.2+版本;

JtaTransactionManager:位于org.springframework.transaction.jta包中,提供对分布式事务管理的支持,并将事务管理委托给Java EE应用服务器事务管理器;

spring事务传播行为

当一个方法的执行被纳入到spring事务管理中时,需要指明事务应怎样传播,例如是忽略事务、还是继续在现有事务中运行、还是新开启一个事务等,这将影响事务的回滚和提交。 spring事务定义了7中传播行为:

其中PROPAGATION_REQUIRED为默认的传播属性

spring事务隔离级别

spring的隔离级别一定是要数据库锁机制支持的,如果数据库不支持某种隔离级别,那么spring设置了也无效。

spring事务超时

spring的事务超时不是某个方法执行完成所耗费的时间,而是每执行一次sql就检查一次时间,两次sql执行期间的其他非数据库操作不计入。 spring事务超时 = 事务开始 + 最后一个数据库操作的执行时间(或超时时间)。 例如:如果配置的事务超时时间为3分钟,情况1:在一个事务方法内顺序的有两个sql执行和一个耗时的非数据库操作,如果两个sql执行时间没有超过3分钟,但是最后一个非数据库操作耗时了5分钟(比如http请求或者线程sleep)那么这个事务会提交,不会回滚。 情况2:在一个事务方法内顺序的有一个sql、一个耗时的非数据库操作、另外一个sql,如果两个sql总执行时间没有超过3分钟,但是非数据库操作耗时了5分钟(比如http请求或者线程sleep)那么这个事务会回滚,因为事务开始时到最后一个sql的执行时间和检查时间超过了设置的超时时间,所以事务回滚。

spring事务回滚规则

默认情况下,事务只有在遇到运行期异常(RuntimeException类或其子类)时才会回滚,而在遇到检查型异常(比如IOException,可被try...catch或throw)时不会回滚。 但是也可以声明事务在遇到特定的检查型异常时像遇到运行期异常那样回滚。另外也可以声明事务遇到特定的异常不回滚,即使这些异常是运行期异常。 注意以下几点:

如果所有异常事务均回滚,可以将spring默认的回滚时的异常修改为Exception

只有非只读事务才能回滚的,只读事务是不会回滚的

如果被try...catch了,catch中没有抛出RuntimeException异常,事务不回滚,抛出RuntimeException异常事务才会回滚

可以申明事务在遇到特定的检查型异常时回滚,需要配置相应的异常类型,使用rollbackFor或者rollbackForClassName。

可以申明事务遇到特定的异常不回滚,使用noRollbackForClassName。

spring事务是否只读

“只读事务”并不是一个强制选项,它只是一个“暗示”,提示数据库驱动程序和数据库系统,这个事务并不包含更改数据的操作,那么JDBC驱动程序和数据库就有可能根据这种情况对该事务进行一些特定的优化,比方说不安排相应的数据库锁,以减轻事务对数据库的压力,毕竟事务也是要消耗数据库的资源的。 如果事务设置了只读属性,如果在方法里包含了新增、修改、删除等非查询数据操作,方法会抛异常,spring默认的readOnly为false。

spring事务配置方式

基础配置如下:

以下5中配置依赖于基础配置:

每个Bean都有一个代理(基于TransactionProxyFactoryBean代理)

所有Bean共享一个代理基类(基于TransactionProxyFactoryBean代理)

使用拦截器

使用tx标签配置的拦截器(AOP)

全注解(方法或类加@Transactional)

spring事务用法

spring事务的相关配置、传播行为、隔离级别、超时、回滚、只读这些属性均已通过testcase测试,由于测试用例及代码较多,限于篇幅限制,代码已上传至github:https://github.com/star9500/spring-tx-demo,如有需求,欢迎fork,欢迎issues。

注意:本项目里用的是spring5.1.3.RELEASE版本

测试用例使用的数据库表结构sql如下:

测试用例说明 测试类里注释比较全,这里只介绍测试用例类的用户,使用时请阅读代码注释

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190128G0OT9300?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券