精华内容
下载资源
问答
  • 事务回滚@Transactional手动提交回滚

    千次阅读 2020-07-02 17:24:03
    (注意:若是在方法类中使用try、catch捕获异常则不会回滚该事务) 2、手动提交回滚 impl中通过这样获取: @Resource(name="transactionManager") private DataSourceTransactionManager transactionManager;...

    1、@Transactional注解
    @Transactional 实质是使用了 JDBC 的事务来进行事务控制的
    @Transactional 基于 Spring 的动态代理的机制

    @Transactional 实现原理:

    1) 事务开始时,通过AOP机制,生成一个代理connection对象,

    并将其放入 DataSource 实例的某个与 DataSourceTransactionManager 相关的某处容器中。

    在接下来的整个事务中,客户代码都应该使用该 connection 连接数据库,

    执行所有数据库命令。

    [不使用该 connection 连接数据库执行的数据库命令,在本事务回滚的时候得不到回滚]

    (物理连接 connection 逻辑上新建一个会话session;

    DataSource 与 TransactionManager 配置相同的数据源)

    2) 事务结束时,回滚在第1步骤中得到的代理 connection 对象上执行的数据库命令,

    然后关闭该代理 connection 对象。

     事务指逻辑上的一组操作,组成这组操作的各个单元,要不全部成功,要不全部不成功。

    一般在项目上有多插入多表字段并且插入的表之间数据有关联时添加事务回滚就显得非常重要。例如插入的第一条数据与第二条数据字段数据大部分相同,但第一条数据插入成功后,第二条数据因为字段原因报错。此时第一条数据就成为脏数据,两条数据无法关联。

    举例事务回滚

    Service实现层代码

    
    @Service
    public class TPeopleServiceImpl implements TPeopleService {
    
        @Autowired
        TPeopleMapper tPeopleMapper;
    
        @Autowired
        TPeopleService tPeopleService;
    
        @Override
        @Transactional(rollbackFor = Exception.class)
        public TPeople savePeople(TPeople params) throws Exception{
            tPeopleMapper.insert(params);
            System.out.println("数据库已插入");
            return params;
        }
    
        @Override
        @Transactional(rollbackFor = Exception.class)
        public int test(TPeople params) throws Exception{
            tPeopleService.savePeople(params);
            System.out.println("------------------------------------------");
            if (params.getName().equals("张三君")){
                throw new Exception("张三军不许入住");
            }
            return 0;
        }

    数据库当前就为一条数据

    添加为张三君的数据

    数据已插入到Mybatis缓存中,当跑完整个流程便插入进数据库

    但是我们现在入参的名称为张三君

    跑完后抛出异常,事务回滚,Mybatis缓存将要插入的数据没有插入进数据库当中。

    数据库还是为一条数据。

    (注意:若是在方法类中使用try、catch捕获异常则不会回滚该事务)

    2、手动提交回滚

    impl中通过这样获取:

    
    @Resource(name="transactionManager")  
        private DataSourceTransactionManager transactionManager;

    具体执行操作:

        DefaultTransactionDefinition def = new DefaultTransactionDefinition();  
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); // 事物隔离级别,开启新事务,这样会比较安全些。  
        TransactionStatus status = transactionManager.getTransaction(def); // 获得事务状态  
        try {  
            //逻辑代码,可以写上你的逻辑处理代码  
            transactionManager.commit(status);  
        } catch (Exception e) {  
            transactionManager.rollback(status);  
        }

     

    展开全文
  • spring 方法加了@Transactional,我想循环一次就提交,怎么搞,开启了事务默认应该是执行完了才全部提交
  • Springboot事务手动回滚或提交

    千次阅读 2020-05-09 14:32:14
    Springboot事务手动回滚或提交 service层的方法被controller层调用时,在方法上加@Transactional注解,操作数据库时会有事务。 @Transactional public void insert() { try { // 业务逻辑 } catch (Exception ...

    Springboot事务手动回滚或提交

    service层的方法被controller层调用时,在方法上加@Transactional注解,操作数据库时会有事务。

    
        @Transactional
        public void insert() {
            try {
               // 业务逻辑
            } catch (Exception e){
               // 异常
            }
        }
        
    

    正常流程下事务会自动提交,异常情形需要开发人员手动处理:
    情景一、异常捕获后事务不回自动回滚,需要手动回滚。(不加try catch或手动抛出异常事务会自动回滚)
    情景二、业务逻辑需要在方法结束前,手动回滚或提交事务

    1、注入事务管理器

    
        @Autowired
        private PlatformTransactionManager platformTransactionManager;
        
    

    2、事务回滚

    
     @Transactional
        public void insert() {
            try {
                // 业务逻辑
            } catch (Exception e){
                // 事务手动回滚
                platformTransactionManager.rollback(TransactionAspectSupport.currentTransactionStatus());
            }
        }
        
    

    3、事务提交

    
     @Transactional
        public void insert() {
            try {
                // 业务逻辑
            } catch (Exception e){
                // 事务手动回滚
                platformTransactionManager.rollback(TransactionAspectSupport.currentTransactionStatus());
            }
            // 事务手动提交
            platformTransactionManager.commit(TransactionAspectSupport.currentTransactionStatus());
    	    // 后续业务逻辑
        }
        
    

    回滚还可以这样写

    
     @Transactional
        public void insert() {
            try {
                // 业务逻辑
            } catch (Exception e){
                // 事务手动回滚
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            }
            // TransactionAspectSupport.currentTransactionStatus()没有事务提交功能
        }
         
    
    展开全文
  • 1.未加事务注解(或者事务配置), 所以需要手动开启事务和手动提交事务和手动回滚事务 @Autowired private PlatformTransactionManager txManager; @Autowired private ShopGroupBuyDao shopGroupBuyDao; @...

    1.未加事务注解(或者事务配置), 所以需要手动开启事务和手动提交事务和手动回滚事务

    @Autowired
      private PlatformTransactionManager txManager;
    
      @Autowired
      private ShopGroupBuyDao shopGroupBuyDao;
    
      @GetMapping(value = "/transactionDemo")
      public void ceshi() {
    
        // 手动开启事务  start
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
        TransactionStatus status = txManager.getTransaction(def);
        // 手动开启事务  end
    
        try {
    
          ShopGroupBuy shopGroupBuy = shopGroupBuyDao.selectOne(new LambdaQueryWrapper<ShopGroupBuy>()
                                                                    .eq(ShopGroupBuy::getGroupBuyId, 505));
    
          shopGroupBuy.setGroupBuyTheme("wulin11");
    
          int i = shopGroupBuyDao.updateById(shopGroupBuy);
    
          int a = 1 / 0;
    
          // 手动提交事务  start
          txManager.commit(status);
          // 手动提交事务  end
    
          if (i > 0) {
            System.out.println("更新成功");
          } else {
            System.out.println("更新失败");
          }
    
        } catch(Exception e) {
    
          e.printStackTrace();
    
          // 手动回滚事务  start
          txManager.rollback(status);
          // 手动回滚事务  end
          
        }
      }

     

     

     

     

    2.加事务注解

    这里演示加了事务注解(@Transactional(rollback=Exception.class)), 且在代码中也加了try catch相当于没有加事务注解, 所以事务不起作用, 此时就需要在catch里面手动添加事务的回滚,即这样:也可以参考博客:https://blog.csdn.net/qq_26106607/article/details/83827630

      @Autowired
      private ShopGroupBuyDao shopGroupBuyDao;
    
      @GetMapping(value = "/transactionDemo")
      @Transactional(rollbackFor = Exception.class)
      public void ceshi() {
    
        try {
    
          ShopGroupBuy shopGroupBuy = shopGroupBuyDao.selectOne(new LambdaQueryWrapper<ShopGroupBuy>()
                                                                    .eq(ShopGroupBuy::getGroupBuyId, 505));
    
          shopGroupBuy.setGroupBuyTheme("wulin11");
    
          int i = shopGroupBuyDao.updateById(shopGroupBuy);
    
          int a = 1 / 0;
    
          if (i > 0) {
            System.out.println("更新成功");
          } else {
            System.out.println("更新失败");
          }
    
        } catch(Exception e) {
    
          e.printStackTrace();
    
          // 手动回滚事务  start
          TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
          // 手动回滚事务  end
    
        }
      }

     

     

     

     

    展开全文
  • 处理springboot 下提交事务异常,数据库没有回滚的问题。 spring的文档中说道,spring声明式事务管理默认对非检查型异常和运行时异常进行事务回滚,而对检查型异常则不进行回滚操作。 什么是检查型异常什么又是非...

    处理springboot 下提交事务异常,数据库没有回滚的问题。

    spring的文档中说道,spring声明式事务管理默认对非检查型异常和运行时异常进行事务回滚,而对检查型异常则不进行回滚操作。

    什么是检查型异常什么又是非检查型异常?
    最简单的判断点有两个:
    1.继承自runtimeexception或error的是非检查型异常,而继承自exception的则是检查型异常(当然,runtimeexception本身也是exception的子类)。

     

    2.对非检查型类异常可以不用捕获,而检查型异常则必须用try语句块进行处理或者把异常交给上级方法处理总之就是必须写代码处理它。所以必须在service捕获异常,然后再次抛出,这样事务方才起效。

     

    结论:

    在spring的事务管理环境下,使用unckecked exception可以极大地简化异常的处理,只需要在事务层声明可能抛出的异常(这里的异常可以是自定义的unckecked exception体系),在所有的中间层都只是需要简单throws即可,不需要捕捉和处理,直接到最高层,比如UI层再进行异常的捕捉和处理。

     

     

    默认规则:

    1 让checked例外也回滚: @Transactional(rollbackFor=Exception.class),一般只需添加这个即可

    2 让unchecked例外不回滚: @Transactional(notRollbackFor=RunTimeException.class)

    3 不需要事务管理的(只查询的)方法:@Transactional(propagation=Propagation.NOT_SUPPORTED),或者不添加

     

    注意: 如果异常被try{}catch{}了,事务就不回滚了,如果想让事务回滚必须再往外抛try{}catch{throw Exception}。因为一旦你try{}catch{}了。系统会认为你已经手动处理了异常,就不会进行回滚操作。

     

    示例:

    @Override  
      @Transactional(rollbackFor = Exception.class)  
      public Integer submitOrder(FlashbuyOrder flashbuyOrder, List<FlashbuyOrderItem> itemList)  
          throws Exception  
      {  
      
          return null;  
      
      }  

     spring 事务控制 设置手动回滚 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

    https://www.cnblogs.com/liuzhenlei/p/6777644.html 

     1 //假设这是一个service类的片段
     2 
     3 try{ 
     4     //出现异常
     5 } catch (Exception e) {
     6             e.printStackTrace();
     7            //设置手动回滚
     8             TransactionAspectSupport.currentTransactionStatus()
     9                     .setRollbackOnly();
    10         }
    11 //此时return语句能够执行
    12 return  xxx;

     

    如上:

      当我们需要在事务控制的service层类中使用try catch 去捕获异常后,就会使事务控制失效,因为该类的异常并没有抛出,就不是触发事务管理机制。怎样才能即使用try catch去捕获异常,而又让出现异常后spring回滚呢,这里就要用到

    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

    完美解决问题。并且能够使该方法执行完。

     

    这个需要注意两点:

    1. 方法上要加上    @Transactional(rollbackFor = Exception.class)   再配合TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); 才可以,否则会报错  NoTransactionException: No transaction aspect-managed TransactionStatus in scope
        at 

    @Transactional(propagation = Propagation.REQUIRES_NEW,
                rollbackFor = Exception.class, isolation = Isolation.REPEATABLE_READ)
        public void testInsert(int index) throws Exception {
            OrderDO orderDO = new OrderDO();
            orderDO.setThirdOrderId("1000");
            int rowCount = this.orderMapper.insertOrder(orderDO);
            if (index == 1) {
                throw new RuntimeException("wrong");
            }
            if (index == 2) {
                throw new Exception("wrong");
            }
            if (index == 3) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            }
        }

    2.  

    Spring Transactional一直是RD的事务神器,但是如果用不好,反会伤了自己。下面总结@Transactional经常遇到的几个场景:

    @Transactional 加于private方法, 无效
    @Transactional 加于未加入接口的public方法, 再通过普通接口方法调用, 无效
    @Transactional 加于接口方法, 无论下面调用的是private或public方法, 都有效
    @Transactional 加于接口方法后, 被本类普通接口方法直接调用, 无效
    @Transactional 加于接口方法后, 被本类普通接口方法通过接口调用, 有效
    @Transactional 加于接口方法后, 被它类的接口方法调用, 有效
    @Transactional 加于接口方法后, 被它类的私有方法调用后, 有效

    Transactional是否生效, 仅取决于是否加载于接口方法, 并且是否通过接口方法调用(而不是本类调用)。

    https://segmentfault.com/a/1190000014617571

     ProductService.java
    /**********************************************************************/
    public interface ProductService{
        Integer getPrice(ProductInfo p);
        Integer compute(ProductInfo p);
    }
    /**********************************************************************/
    
    
    ProductServiceImpl.java
    /**********************************************************************/
    @Service
    public class ProductServiceImpl implements ProductService{
        @Autowired
        private ProductService productService;
        
        public Integer getPrice(ProductInfo p){
            productService.compute(p);
        }
    
        @Transactional(rollbackFor = Exception.class)
        public Integer compute(ProductInfo p){ 
            try{
                ...
            }catch(Exception e){
                 e.printStackTrace();
                 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                 return 0;
            }
        }
    }
    
    是可以的,因为是通过接口调用了
     ProductService.java
    /**********************************************************************/
    public interface ProductService{
        Integer getPrice(ProductInfo p);
      
    }
    
    public interface MyService{
      
        Integer compute(ProductInfo p);
    }
    /**********************************************************************/
    
    
    ProductServiceImpl.java
    /**********************************************************************/
    @Service
    public class ProductServiceImpl implements ProductService{
        @Autowired
        private MyService   myService   ;
        
        public Integer getPrice(ProductInfo p){
            myService.compute(p);
        }
    
      
    }
    
    
    @Service
    public class MyServiceImpl implements MyService{
       
    
        @Transactional(rollbackFor = Exception.class)
        public Integer compute(ProductInfo p){ 
            try{
                ...
            }catch(Exception e){
                 e.printStackTrace();
                 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                 return 0;
            }
        }
    }
    
    放在两个接口类里面,然后通过接口方法调用,是可以生效的

     

     

     

    展开全文
  • springboot 开启事务以及手动提交事务

    万次阅读 多人点赞 2019-03-26 14:55:19
    springboot 开启事务以及手动提交事务 需要在服务类上加上两个注解 @Autowired DataSourceTransactionManager dataSourceTransactionManager; @Autowired TransactionDefinition transactionDefinition; 手动开启...
  • SpringBoot手动提交事务

    万次阅读 2019-09-06 11:06:48
    Springboot内部提供的事务管理器是根据autoconfigure来进行决定的。 比如当使用jpa的时候,也就是pom中加入了spring-boot-starter-data-jpa这个starter之后(之前我们分析过springboot的自动化配置原理)。 ...
  • 1、以下代码存在并发问题,原因是@Transactional开启事务后,执行完createOrder()方法后已经释放锁了,但是事务还没提交,此时另外一个线程获取到锁开始执行createOrder方法导致的 public class ...
  • 要知道,普遍情况下,一般是是使用@Transactional来进行自动事务提交或回滚的。 那么,在SpringBoot中,我们该如何实现呢? SpringBoot实现手动事务 我现在举例实现一个业务。 有两个Service层的方法,他们都在同一...
  • spring boot手动提交事务

    千次阅读 2019-11-16 16:11:25
    spring boot手动提交事务 import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction....
  • 今天在工作中遇到了一个spring事务的问题: 在service方法内需要通过线程去执行添加用户积分和用户积分日志的情况,试了下通过@Transactional声明式事务不起作用,只能使用手动事务去控制 因此写了这篇博客,记录一下这...
  • SSM框架中可以自动提交事务和手动提交事务结合使用吗?如果可以该怎么操作?
  • Spring手动提交事务

    2021-01-07 14:04:29
    Spring事务手动提交 事务背景: Spring事务开启,常见的可以用基于注解的方式进行: @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW) 手动进行Sring事务的提交 ...
  • 手动事务提交

    千次阅读 2019-12-02 17:09:54
    我们现在进行事务控制一般都是使用注解型事务,然而有些时候却会发现注解型事务失效了。比如下方的这种情况: @Transactional(propagation= Propagation.REQUIRES_NEW,rollbackFor = Exception.class) @Override ...
  • Mybatis手动提交事务

    千次阅读 2019-02-27 14:37:36
    ... import java.util.List; import java.util.Map;... //手动提交事务 @Transactional(propagation= Propagation.REQUIRES_NEW) public void insertBalance215Data(Map, Object> list); }  
  • 想要的效果就是 使用了Transactional来开启事务,但可能我在业务中会手动提交事务,spring在到了需要自动提交事务的时候,如果发现事务已经被提交了,就不要报错或者直接就不要再提交事务了 请问有没有什么办法?
  • 之前关于Spring事务只是简单的了解,直接在项目的applicationContext里面直接配置了事务管理之后,就不用关心事务的提交了,spring会帮我们自动提交事务,在异常时直接抛出运行时...但是手动提交事务又不懂,又开始...
  • 手动回滚: ...方法2:例如service层处理事务,那么service中的方法中不做异常捕获,或者在catch语句中最后增加throw new RuntimeException()语句,以便让aop捕获异常再去回滚,并且在service上层(webser.
  • @Transactional 事务处理注解详解

    万次阅读 2019-04-25 10:28:22
    @Transactional 事务处理注解详解 一、 事物注解方式: @Transactional 当标于类前时, 标示类中所有方法都进行事物处理,例子: @Transactional public class TestServiceBean implements TestService {} 当类...
  • 先看下@Transactional可以配制那些参数及以其所代表的意义。 isolation 枚举org.springframework.transaction.annotation.Isolation的值 事务隔离级别 noRollbackFor Class&amp;lt;? extends Throwable&...
  • @[TOC] 目录 NO1.框架自动提交事务与异常回滚 NO2.控制框架的提交和事务回滚 NO3.AOP+注解实现事务的提交和回滚 NO4.spring事务源码解读
  • springboot 手动开启事务,分段提交.

    千次阅读 2019-10-09 13:30:55
    List<OrdLogSyn> ordLogSynList = ordLogSynMapper.batchQuery("AP", "20190926", "0", "1000"); for (int i = 0; i < 2; i++) { DefaultTransactionDefinition def = new DefaultTra...
  • 开启事务之后,不能没有commit或者回滚就return,return并没有关闭数据库连接会造成数据库连接池的连接数超过设置最大值 可以参考这种写法 try{ // 事务定义 DefaultTransactionDefinition def = new ...
  • Spring 的@Transactional 如何开启事务

    千次阅读 2015-03-13 10:36:08
    //提交事务     commitTransactionAfterReturning(txInfo);    return  retVal;   .......   }  }  进入createTransactionIfNecessary(tm,txAttr, ...
  • try-catch处理代码块的时候会捕获异常,要用return返回提示信息,必须手动回滚事务。如果不会滚可以在catch里throw new RuntimeException。或者使用注解@Transactional(rollbackFor = { Exception.class }) 最后...
  • 分布式事务(一)—本地事务及@Transactional使用、失效原因及解决方案
  • 自动提交,每个语句是一个事务 手动提交,所有语句为一个事务
  • public方法或public类加上注解@Transactional,spring boot自动管理事务的开启,提交和回滚。private无效。 手动开启事务提交和管理 添加依赖 compile "org.springframework.boot:spring-boot-starter-data-jpa...
  • 对于Transactional注解的使用这里不过多介绍,这里主要说一下Transactional中的嵌套事务,首先说明,**Mysql是不支持嵌套事务的。**但是Transactional中可以有

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,810
精华内容 3,524
关键字:

transactional手动提交事务