事务管理

在spring中,事物管理一般分为两类,编程式事务管理声明式事务管理
编程式事务管理,一般我们使用TransactionTemplate来实现。

声明式事物管理本质上是spring AOP的实现,对目标方法进行拦截,在目标方法之前加入事务,在执行完目标方法之后根据执行情况,进行回滚或者提交两种操作。

下面分别介绍两种方式的实现

编程式事务管理

首先是xml配置

<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate"><property name="transactionManager" ref="transactionManager"></property></bean><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property></bean>

这里配置事务管理器的时候spring为不同的orm框架实现了不同的platformTransactionManager接口实现

事务 orm框架
org.springframework.jdbc.datasource.DataSourceTransaction spring jdbc和ibatis
org.springframework.orm.hibernate3.Hibernate.TransactionManager hibernate3.0
org.springframework.orm.jpa.JpaTransactionManager spring data JPA
org.springframework.jdo.JdoTransactionManager 持久化机制Jdo
org.springframework.transaction.jta.JtaTransactionManager 使用JTA

常用的主要是上面两种

使用时

this.getTransactionTemplate().execute(new TransactionCallback()){public Object doInTransaction(TransactionStatus arg0){操作数据库语句a操作数据库语句b
}
}
声明式事务管理

它主要是基于AOP实现,在使用时首先配置xml

 <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property></bean><tx:annotation-driven transaction-manager="transactionManager">

这要我们就可以直接在代码中使用@Transactional注解来开启事务

    @Transactionalpublic void deleteUser(Long userId) throws VaException {//操作数据库语句a//操作数据库语句b}

此时如果中途发生异常,已执行的操作会回滚。

springboot使用事务注解@Transactional

springboot使用事务,只需要在类或者方法上标注@Transactional即可。springboot会根据我们使用的orm框架自动配置合适的事务管理器。

但是需要注意的是springboot中使用@Transactional可能失效的问题:
1.Spring 只会回滚运行时、未检查异常(继承自 RuntimeException 的异常)或者 Error和未被catch的异常 这是由于spring底层实现transactionTemplate决定的看源码

public <T> T execute(TransactionCallback<T> action) throws TransactionException {Assert.state(this.transactionManager != null, "No PlatformTransactionManager set");if (this.transactionManager instanceof CallbackPreferringPlatformTransactionManager) {return ((CallbackPreferringPlatformTransactionManager)this.transactionManager).execute(this, action);} else {TransactionStatus status = this.transactionManager.getTransaction(this);Object result;try {result = action.doInTransaction(status);} catch (Error | RuntimeException var5) {     //错误和运行期异常this.rollbackOnException(status, var5);throw var5;} catch (Throwable var6) {this.rollbackOnException(status, var6);throw new UndeclaredThrowableException(var6, "TransactionCallback threw undeclared checked exception");}this.transactionManager.commit(status);return result;}}

2.@Transactional 注解只能应用到 public 方法才有效

所以当你有checked类型的异常时,你可以通过设置属性来是注解生效(可以是一个或者多个)
如@Transactional(rollbackFor=RuntimeException.class)
还有如下一些常用参数:
readOnly: 设置当前事务是否为只读事务,设置为true表示只读,false则表示可读写,默认值为false

noRollbackFor:设置不需要进行回滚的异常类数组,当方法中抛出指定异常数组中的异常时,不进行事务回滚

propagation:设置事务的传播行为

isolation:设置底层数据库的事务隔离级别,事务隔离级别用于处理多事务并发的情况,通常使用数据库的默认隔离级别即可。

timeout :事务的超时时间,默认值为-1(表示不限时间)。如果超过该时间限制但事务还没有完成,则自动回滚事务,单位为second

因为spring使用AOP技术动态代理来实现@Transactional,但是动态代理有两种,spring如何选择?如果一个类有顶层接口,则默认使用jdk的动态代理来代理,如果直接是一个类,则使用cglib动态代理。

事务的隔离级别

@Transactional(isolation = Isolation.READ_UNCOMMITTED):读取未提交数据(会出现脏读,
不可重复读) 基本不使用

@Transactional(isolation = Isolation.READ_COMMITTED):读取已提交数据(会出现不可重复读和幻读)

@Transactional(isolation = Isolation.REPEATABLE_READ):可重复读(会出现幻读)

@Transactional(isolation = Isolation.SERIALIZABLE):串行化

事务传播行为

TransactionDefinition.PROPAGATION_REQUIRED:
如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。这是默认值。

TransactionDefinition.PROPAGATION_REQUIRES_NEW:
创建一个新的事务,如果当前存在事务,则把当前事务挂起。

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

TransactionDefinition.PROPAGATION_NOT_SUPPORTED:
以非事务方式运行,如果当前存在事务,则把当前事务挂起。

TransactionDefinition.PROPAGATION_NEVER:
以非事务方式运行,如果当前存在事务,则抛出异常。
TransactionDefinition.PROPAGATION_MANDATORY:
如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。

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

编程式事务和声明式事务浅析相关推荐

  1. [事务] 编程式事务和声明式事务的优缺点

    事务管理在系统开发中是不可缺少的一部分,Spring提供了很好事务管理机制,主要分为编程式事务和声明式事务两种. 关于事务的基础知识,如什么是事务,数据库事务以及Spring事务的ACID.隔离级别. ...

  2. Spring笔记(4) - Spring的编程式事务和声明式事务详解

    一.背景 事务管理对于企业应用而言至关重要.它保证了用户的每一次操作都是可靠的,即便出现了异常的访问情况,也不至于破坏后台数据的完整性.就像银行的自助取款机,通常都能正常为客户服务,但是也难免遇到操作 ...

  3. react 编程式导航和声明式导航

    react中的两种路由导航方法[声明式导航.编程式导航] 主要使用的方法 [Link , NavLink , props, useHistory() ,Route],推荐使用前四个方法,更简单高效 1 ...

  4. Spring的编程式事务声明式事务 基于注解的声明式事务控制

    文章目录 Spring中编程式事务 基于XML的声明式事务控制 基于注解的声明式事务控制 Spring集成web环境 Spring中编程式事务 Spring的事务控制可以分为编程式事务控制和声明式事务 ...

  5. spring控制事务:声明式事务(XML)事务的传播行为

    声明式事务(XML) 使用spring提供的专用于mybatis的事务管理器在xml中声明式事务 声明式事务需要使用到的标签 tx配置 进行<tx 标签的使用需要在xml头部导入命名空间 xml ...

  6. Spring编程式和声明式事务实例讲解

    历史回顾: 可能是最漂亮的Spring事务管理详解 Spring事务管理 Spring支持两种方式的事务管理: 编程式事务管理: 通过Transaction Template手动管理事务,实际应用中很 ...

  7. 编程式事务和声明式事物

    编程式事务 声明式事物

  8. java编程式事务_Spring编程式和声明式事务实例讲解

    Spring事务管理 Spring支持两种方式的事务管理: 编程式事务管理: 通过Transaction Template手动管理事务,实际应用中很少使用, 使用XML配置声明式事务: 推荐使用(代码 ...

  9. spring编程式和声明式事务控制

    可优先参考:@Transactional Spring 事务的深入学习与使用[两万字] 1. 编程式事务控制 @Autowired private RoleMapper roleMapper;@Aut ...

最新文章

  1. 如何使用 Python 创建一名可操控的角色玩家
  2. Socket,SocketImpl与SocketImplFactory的关系
  3. 深度学习训练的小技巧,调参经验。总结与记录。
  4. Java中重写equals()方法时注意点
  5. 利用动态规划(DP)解决 Coin Change 问题
  6. 集成学习(二)——XGBoost
  7. 自动化办公-Python处理Excel生成试卷
  8. java学术论文_java毕业设计论文-学术参考网
  9. 车站计算机系统的简称,AFC计算机系统.ppt
  10. 郑州等保测评公司有哪些?在哪里?
  11. UE4插件研发 So Easy
  12. android exo解码问题,android – exoplayer-自动更改质量不起作用(hls)
  13. 普通路由器改4g路由器_工业远程管理神器,4G无线路由器更方便
  14. Testin融资后首个举措:推出O2O一站式测试服务
  15. Error: [$injector:unpr] angular.js
  16. (Python)常用高级函数:print的使用
  17. “新华三杯”全国大学生数字技术大赛预选赛备考资料
  18. 248Echarts - 3D 曲面(Parametric Surface Rose)
  19. Vue - 音频播放器插件(vue-aplayer)
  20. 技能提升之Latex控制图片位置

热门文章

  1. 单片机开发:不得不了解的看门狗电路
  2. 被动信息收集(一)nslookup.dig.DNS字典爆破.whois
  3. 2-6_Cleaning_Data清洗数据
  4. ArcGIS 中的标准分类方法
  5. 程序员在家办公太无聊,推荐你看完这十部电影。收货满满
  6. Word doc/docx 格式文件转换为 MarkDown
  7. docx转换为doc格式,公式变成图片问题,word2016
  8. Vue | 显示切换(v-if与v-show,display,visibility与opacity)
  9. 阿德莱德大学语言班成绩为C,阿德莱德大学语言课程要读多久?先看看你的雅思成绩……...
  10. python基础知识点大全