Spring——声明式事务详解编程语言
Spring的声明式事务使用起来比较简单,[email protected],就将一个方法变成事务方法了。使用声明式事务,可以将事务管理代码从业务方法中抽离出来(也就是不用在方法里写commit和rollback),以声明的方式来实现事务管理。
Spring的核心事务管理抽象是PlatformTransactionManager,要想使用声明式事务,必须先在xml中先将其声明为bean,而且还要记得配置数据源
!--这么写就可以扫描到db.properties的配置信息-- context:property-placeholder location="classpath:db.properties" /context:property-placeholder !--配置数据源-- bean id = "dataSource" class = "com.alibaba.druid.pool.DruidDataSource" property name="username" value="${jdbc.username}" /property property name="password" value="${jdbc.password}" /property property name="url" value="${jdbc.url}" /property property name="driverClassName" value="${jdbc.driverName}" /property /bean !--配置事务管理器的bean对象-- bean id="transactionManager" property name="dataSource" ref="dataSource" /property /bean !--如果代码中用到jdbc操作数据库,可以加下面的配置-- !--将JdbcTemplate注册为bean-- bean id="jdbcTemplate" property name="dataSource" ref="dataSource" /property /bean !--开启事务管理器的配置-- tx:annotation-driven transaction-manager="transactionManager" /tx:annotation-driven
#db.properties jdbc.username = root jdbc.password = root jdbc.url = jdbc:mysql://localhost:3306/tx jdbc.driverName = com.mysql.jdbc.Driver@Transactional
下面说明一下Transactional里的重要参数
ioslation:隔离级别。可配置为可重复读,读已提交,读未提交,序列化,DEFAULT(这个配置将使用选择的数据库的默认事务隔离级别)
rollbackFor:指定一个或多个异常,当方法发生这个异常时,回滚
如 @Transactional(rollbackFor = {java.lang.ArithmeticException.class})。这一项,强烈建议每个声明式事务都必须配置
rollbackForClassName:与上同,只是传参形式不同
如@Transactional(noRollbackForClassName = "java.lang.ArithmeticException")
noRollbackFor:指定一个或多个异常,当方法发生这个异常时,不回滚
如 @Transactional(noRollbackFor = {java.lang.ArithmeticException.class})
noRollbackForClassName:与上同,只是传参形式不同
如 @Transactional(noRollbackForClassName = "java.lang.ArithmeticException")
事务的传播特性
传播特性:表示不同事务之间执行的关系。或者说当一个事务方法A被另一个事务方法B调用时,A和B会发生怎样的关系
下面的文字比较绕,如果看不懂(一般人都看不懂…)直接看下面的例子解释就行
注意下面所有multi方法与buyBook和updatePrice不在一个类中。若在一个类,multi对buyBook和updatePrice的调用将会是普通调用,不会产生事务传播特性
@Transactional() public void multi(){ bookService.buyBook(); [email protected](propagation = Propagation.REQUIRED) bookService.updatePrice(BOOK_ID); [email protected](propagation = Propagation.REQUIRED)
REQUIRED的效果是:当内部的事务方法配置了REQUIRED之后,事务的控制交由外部事务方法(multi)控制。也就是说,将buyBook和updatePrice统一成一个事务,只有buyBook和updatePrice都commit时,整个multi才算commit。不论buyBook还是updatePrice发生异常(不论是否在multi被try-catch捕获),二者都会rollback,一个都不会commit。如果取消multi的事务声明使之变为普通方法,那么buyBook和updatePrice,谁发生异常谁rollback,不影响另一个方法的commit
REQUIRES_NEW@Transactional() public void multi(){ bookService.buyBook(); [email protected](propagation = Propagation.REQUIRES_NEW) bookService.updatePrice(BOOK_ID); [email protected](propagation = Propagation.REQUIRED)
REQUIRES_NEW的效果是:配置成REQUIRES_NEW的方法会单独执行一个事务,若buyBook发生异常(不论是否被try-catch捕获),则buyBook会rollback,不影响updatePrice的commit。从REQUIRES_NEW这一名字就可联想到,配成REQUIRES_NEW的方法,需要一个新事务单独执行,而由于事务的隔离性,所以配成REQUIRES_NEW的事务不会影响其他事务,即使它们被捆绑到同一个事务方法(multi)里
SUPPORTS@Transactional() public void multi(){ bookService.buyBook(); [email protected](propagation = Propagation.SUPPORTS)
SUPPORTS的效果是:如果multi是事务方法,则buyBook受事务控制。如果multi是普通方法,则buyBook不受事务控制(即,发生异常的代码前的逻辑会成功commit,发生异常代码后的逻辑会报错失败)。SUPPORTS方式几乎不用
NOT_SUPPORTED@Transactional() public void multi(){ bookService.buyBook(); [email protected](propagation = Propagation.NOT_SUPPORTED)
NOT_SUPPORTED的效果是:不论multi是不是事务方法,buyBook均不受事务控制(即,发生异常的代码前的逻辑会成功commit,发生异常代码后的逻辑会报错失败)。NOT_SUPPORTED方式几乎不用
MANDATORY[email protected]() public void multi(){ bookService.buyBook(); [email protected](propagation = Propagation.NEVER)
NEVER的效果是:必须在buyBook外面再套一层事务方法,否则会报下列错误。MANDATORY几乎不用(唯一的用处可能就是,强制让其他程序员在使用buyBook时,必须要与其他事务一起使用,捆绑在一个事务里)
@Transactional() public void multi(){ bookService.buyBook(); [email protected](propagation = Propagation.NEVER)
NEVER的效果是:不允许buyBook外面再套一层事务方法,否则会报下列错误。NEVER与MANDATORY正好相反。NEVER方式几乎不用(唯一的用处可能就是,强制让其他程序员在使用buyBook时,不允许再在外层套一个事务方法)
@Transactional(rollbackFor = { java.lang.ClassCastException.class}) public void multi(){ try { bookService.buyBook();[email protected](propagation = Propagation.NESTED) }catch(Exception e){ bookService.updatePrice(BOOK_ID);[email protected] int i = 1/0;
NEVER的效果是:如果buyBook方法发生异常(updatePrice无异常),不被捕获,则buyBook和updatePrice都不会回滚。可是如果buyBook被捕获了,并且multi发生异常时,则buyBook和updatePrice都会回滚。一句话说就是:NESTED的配置会导致,不论multi里怎么对异常方法处理了,所有方法均会回滚。换言之,multi里的所有方法,都被multi里都异常所制约
对REQUIRED,REQUIRES_NEW,NESTED做一个区别
REQUIRED:将所有事务方法捆绑为一个事务,一荣俱荣,一殒具殒 REQUIRES_NEW:单独将配置成REQUIRES_NEW的那个事务视为独立的事务,不管它有没有被捆绑到外部事务中,不管外部事务是否发生异常,它的成功commit与否,均与其他事务无关。 NESTED:不论被捆绑的事务在外部事务中做了怎样的异常捕获,均被外部事务中的异常所制约,一旦外部事务发生异常,所有捆绑到外部事务中的事务,都要回滚。原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/20577.html
cjavamysqlxml相关文章
- Spring学习笔记(五)——JdbcTemplate和spring中声明式事务
- 简单介绍一下spring bean的生命周期_Spring bean的生命周期
- Spring MVC框架学习(五) ---- 传递参数
- batch spring 重复执行_Spring Batch批处理
- java面试题 --- Spring③
- 理论:第二章:Spring的AOP和IOC是什么?使用场景有哪些?Spring事务与数据库事务,传播行为,数据库隔离级别
- spring整合s3实现文件上传下载
- Spring:声明式事务
- Spring事务回滚的两种方法
- Spring Boot 2.x基础教程:配置元数据的应用
- 事务隔离属性、spring传播属性、 @Transactional注解详解数据库
- Spring事务的传播特性详解编程语言
- spring事务与消息队列详解编程语言
- Spring事务传播特性的浅析和事务方法嵌套调用详解编程语言
- Spring在xml配置里配置事务详解编程语言
- Spring Boot2.0之 整合Redis事务详解编程语言
- Spring Boot2.0之多数据源分布式事务问题详解编程语言
- spring Boot(十九):使用Spring Boot Actuator监控应用详解编程语言
- Spring Boot(十五):spring boot+jpa+thymeleaf增删改查示例详解编程语言
- Spring Boot(十三):spring boot小技巧详解编程语言
- Spring事务异常回滚,捕获异常不抛出就不会回滚详解编程语言
- spring boot @RequestBody数据传递及解析详解编程语言
- MyBatis与Spring的整合步骤
- Spring框架下整合Redis的实现(spring整合redis)
- spring架构利器:JFinal MySQL Spring(jfinalmysql)
- spring实现jdbctemplate添加事务支持示例
- 通过spring用beanshell实现java接口示例