栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring事务管理

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring事务管理

目录

Spring 提供的事务管理方案

编程式事务管理

声明式事务管理

事务嵌套

Spring 提供的事务管理方案

编程式事务管理

两种方式:PlatformTransactionManager和TransactionTemplate

官方推荐使TransactionTemplate进行事务管理,spring对TransactionTemplate提供了两个callback接口,TransactionCallback和TransactionCallbackWithoutResult,二者的唯一区别就是是否需要返回执行结果,使用TransactionTemplate进行事务操作的模板如下:

TransactionTemplate.execute((TransactionStatus status) {
                    //事务操作
                 return null;
 });

在TransactionCallback事务操作过程中如果发生异常需要让当前事务回滚,从Spring对TransactionCallback接口注释可以看出,在发生RuntimeException这种“unchecked exception”时,会触发事务的回滚。

public interface TransactionCallback {
           
           T doInTransaction(TransactionStatus status);
 }

如果在事务运行中发生了“checked exception”,若没处理异常,TransactionTemplate模板不会对事务进行回滚,如果要回滚有两种方式:
1.捕获异常,然后转译为“unchecked exception”后抛出,TransactionTemplate进行事务的回滚,可以先
2.TransactionCallback接口的TransactionStatus标记为rollBackOnly,TransactionTemplate在提交事务的时候如果检测到rollBackOnly标志状态被设置,则会进行事务回滚。

TransactionTemplate.execute((TransactionStatus status) -> {
        try {
            wrsUserPriorityDetailManager.
                    insertBatch(detailDTOListNeedToInsert);
        } catch (Exception e) {
            status.setRollbackonly();
        }
        return null;
 });

TransactionTemplate继承了DefaultTransactionDefinition,DefaultTransactionDefinition拥有多个设置事务属性的方法,如setTimeout(设置事务超时时间),setIsolationLevel(设置事务的隔离级别)。

声明式事务管理

基于注解@Transactional实现对类和方法进行事务标注,修饰类表示对整个类起作用,修饰方法则仅对方法起作用。



 
@Transactional(rollbackFor = Exception.class)
public void insertRecord() throws Exception{
             WrsHistoryTaskDO wrsHistoryTaskDO = iniWrsHistoryTaskDO();
             Long id = wrsHistoryTaskDAO.insert(wrsHistoryTaskDO);
    }
rollbackFor是注解的属性,上面的例子表示遇到Exception时回滚。
@Transactional注解包含多个属性可以控制事务的属性:
       
属性名                               说明
propagation                     事务的传播行为
isolation                       事务的隔离级别
readonly                        事务的读写性
timeout                         超时时间
rollbackFor                     一组异常类,遇到时进行回滚

如果报错显示等待锁超时,但是打开DefaultTransactionDefinition发现事务隔离级别和超时分别设置为ISOLATION_DEFAULT和TIMEOUT_DEFAULT(这两个参数表示默认的事务隔离级别和默认的超时时间),但是TIMEOUT_DEFAULT的值为-1,所以Spring并没有启用事务超时时间,此时使用的超时时间是mysql的事务超时时间,查看mysql的事务超时时间的sql为:show variables like '%timeout%';其中innodb_lock_wait_timeout变量指明了innodb中行锁的等待超时时间,在idb中查看默认超时时间为5s。这里的解决方案是将大的事务进行拆分变成多个小事务,避免进行长时间的持有行锁。

事务嵌套

下面事务默认的传播机制是required,循环十次,每一次都执行新增操作,到第十次时抛出运行时异常,此时数据库记录是为空的,如果传播机制换成supports,数据库中应该是有9条记录。

@Transactional
public void inserBatch() {
      for (int i = 0; i < 10; i++) {
          if (i == 9) {
              throw new RuntimeException();
           }
           userService.insertA();
       }
}

ServiceB#methodB的事务属性为PROPAGATION_REQUIRES_NEW,methodB是一个独立的事务,与外层事务没有任何关系,如果methodB执行失败,methodA的调用会抛出异常,导致methodA的事务回滚。事务B不受事务A的影响(除了在执行事务B之前事务A就抛出了异常这种情况)

@Transactional(propagation = Propagation.REQUIRED, readonly = false)
public void methodA() {
     serviceA.inserBatch();
     String id = IdGenerator.generatePayId("A");
     System.out.println(id);
     serviceB.methodB();  
}
@Transactional(propagation = Propagation.REQUIRES_NEW, readonly = false)
public void methodB() {
     String id = IdGenerator.generatePayId("B");
     System.out.println(id);
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/764165.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号