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

Spring 事务超时时间

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

Spring 事务超时时间

问题:生产环境下插入大量数据,日志报错,数据最终没有入库,显示state报错。

测试和结论:Transactional中设置超时时间5秒,代码中先插入数据,后sleep数秒,没有报错。用另外一个线程更新锁定一个数据后不提交事务,然后再开一个线程去更新此数据,之后报错了,说明超时时间指的是数据库执行最多能用的时间,不是java程序执行的时间。

在spring中如何使用事务是一个很大的问题,其中有一个我需要在这篇文章中着重讲解一下,就是spring事务中的超时时间问题,很多同学不知道如何才能是这个超时时间生效,导致在使用过程中出现各种各样的问题。

1、使用mybatis框架来做数据库操作
代码案例如下:

@Transactional(propagation = Propagation.REQUIRED,timeout = 5)
    @Override
    public int addArea(ConsultConfigArea area) {
        int i = commonMapper.addArea(area);
        try {
            TimeUnit.SECONDS.sleep(7);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return i;
    }

可以看到在@Transactional注解里面设置了一个timeout=5,这里的时间单位是秒。我们在程序里面休眠了7秒,我们测试一下:
保存一个“XJ77”的数据,测试代码如下:

    @Test
    public void addAreaTest() {
        AreaService bean = applicationContext.getBean(AreaService.class);
        ConsultConfigArea area = new ConsultConfigArea();
        area.setAreaCode("XJ77");
        area.setAreaName("XJ77");
        area.setState("1");
        bean.addArea(area);
    }

单元测试的日志打印如下:
从日志打印效果来看,确实是已经提交了事务的,跟我们的预期不一样,事务设置的超时时间是5s,休眠了7s但是事务还是提交了。

数据库中的数据:
数据也成功的插入了


从这个现象来看,是不是意味着spring事务注解设置的timeout失效了呢? 

为什么会这样呢?我们来读读源码
1、首先我们看看@Transactional(propagation = Propagation.REQUIRED,timeout = 5)中的timeout是如何读取的。

我们来到事务通知类TransactionInterceptor

开启事务

开启事务

dobegin
在dobegin中从连接池中获取到连接对象

 

在dobegin方法中把超时时间设置到一个deadline变量中

 

以上就是spring中把超时时间设置到了一个deadline变量中,接下来我们读读mybatis源码:
int i = commonMapper.addArea(area);执行流程

MapperProxy

 

最终执行到这里

进入到prepareStatement方法

从这里获取超时时间,我们看看transaction.getTimeout().

从ThreadLocal中获取连接对象,这个ThreadLocal的值是spring中的dobegin方法中设置的

把从spring事务中配置的超时时间设置到了statement对象中


从mybatis源码来看,spring事务注解设置的超时时间,最终在mybatis里面是设置到了statement对象中了,是用jdbc对象来控制sql的执行时间的,如果执行时间超过了设置时间就会抛出异常,这个异常就会被spring事务切面捕获到最终导致事务回滚

其实这里休眠10s是不影响mybatis的sql执行的,sql执行就是5s,如果超过5s就会抛出异常,而这个10s是我们的业务代码不会影响mybatis的sql执行。

所以透过现象看本质,我们业务代码里面休眠10s最终事务提交了,这个是正常现象,因为sql执行没有超过5s的。

 

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

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

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