zoukankan      html  css  js  c++  java
  • Spring事务采坑 —— timeout

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
    本文链接:https://blog.csdn.net/qq_18860653/article/details/79907984
    问题描述
    在使用Spring 事务的时候,加上了timeout的限制,@Transactional(timeout = 10),发现事务不会因为超时回滚。

    功能描述
    所谓事务超时,就是指一个事务所允许执行的最长时间,如果超过该时间限制但事务还没有完成,则自动回滚事务。在 TransactionDefinition 中以 int 的值来表示超时时间,其单位是秒。
    默认设置为底层事务系统的超时值,如果底层数据库事务系统没有设置超时值,那么就是none,没有超时限制。

    问题原因
    Spring事务超时 = 事务开始时到最后一个Statement创建时时间 + 最后一个Statement的执行时超时时间(即其queryTimeout)。所以在在执行Statement之外的超时无法进行事务回滚。

    解决办法
    举个例子

    @Transactional(timeout = 2, rollbackFor = Exception.class,isolation = Isolation.DEFAULT)
    public void createOrder(Integer userId, Integer goodsId, Integer amount) throws Exception {
    //减少库存
    int result = goodsDao.updateGoodsStock(goodsId, amount);
    if (result != 1) {
    throw new Exception("创建订单失败");
    }
    //制造异常
    // int i = 1/0;
    //插入订单
    orderDao.insert(userId, goodsId, amount);
    Thread.sleep(3000);
    }
    在段代码中,如果把Thread.sleep(3000);放到最后,并不会回滚。所以开发的时候要特别注意。如果真的有特别重要的操作(在最后一个Statement之后),我现在的解决办法是,
    * 尽量在执行Statement的中间
    * 在操作的最后再加一个无关的轻量Statement操作

    原理
    有时间在看,肯定是Spring AOP里面的



  • 相关阅读:
    zoj 3195 Design the city LCA Tarjan
    hdu 2586 How far away ? 离线LCA
    洛谷 P3379 【模板】最近公共祖先(LCA)Tarjan离线
    codeforces #446 892A Greed 892B Wrath 892C Pride 891B Gluttony
    设计模式(16)---原型模式
    设计模式(15)---享元模式
    设计模式(14)---组合模式
    设计模式(13)---外观模式
    设计模式(12)---适配器模式
    设计模式(11)---代理模式
  • 原文地址:https://www.cnblogs.com/renjiaqi/p/11688764.html
Copyright © 2011-2022 走看看