超时分类

超时根据作用域可做如下层级划分:

Transaction Timeout > Statement Timeout > JDBC Driver Socket Timeout
Transaction Timeout指一组SQL操作执行时应在设定的时间内完成(提交或回滚),否则将引发超时。它的值应大于 N(语句数) * Statement Timeout
Statement Timeout指完成单条SQL语句执行的最大允许时间。它的值应小于JDBC Driver Socket Timeout的值,因为后者会被先检查。
最底层的JDBC Driver Socket Timeout指的是通过socket进行连接时的超时或者进行读写操作时的阻塞超时,如果不设置将使用OS层的Socket Timeout值。

超时设置
大部分场景中,应用主要关心Transaction Timeout的设置,除非Transaction中总是只有单条Statement。超时的具体设置依赖于使用的数据访问框架或者JDBC Driver。如果使用Spring作为基础框架,可以通过为transactionManager的defaultTimeout属性来设置全局的Transaction Timeout,或者在声明式事务(tx:attributes)的配置中为特定的或所有的方法指定timeout属性的值,还可以在注解式事务@Transactional标记中通过timeout参数来设置。
注意:
1.“Spring事务超时 = 事务开始时到最后一个Statement创建时时间 + 最后一个Statement的执行时超时时间(即其queryTimeout)。”(3)
2. 如果选择JpaTransactionManager作为事务管理器,需要Spring版本在3.0.0之上才能使timeout设置正常工作;
3. 如果选择DataSourceTransactionManager,事务内所有的sql操作必须通过JdbcTemplate执行才能使timeout设置正常工作,通过其他orm(如myBatis)执行的sql操作将无法应用超时设置。这种模式下需要按照具体orm框架的要求配置超时(例如myBatis的defaultStatementTimeout 4)
 
在某些场景中,确实存在混用两种数据访问框架的情况(姑且不讨论这种情况是否合理)。例如在同一事务中混用JdbcTemplate和MyBatis,在这种场景中,为@Transactional或tx:attributes设置的timeout将不会对非JdbcTemplate部分的操作生效,因此实际上已无法控制这个事务的超时。此时,有一种“变通”的方式能够使两种数据访问框架能够“共享”超时设置,那就是设置JDBC Driver Socket阻塞超时。如果使用的是Oracle数据库,并且数据源使用的是DBCP的BasicDataSource,可以在其connectionProperties属性中设置此值,例如:
 

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<!-- 设置毫秒单位的阻塞超时 -->
<property name="connectionProperties" value="oracle.net.READ_TIMEOUT=1000"/> <!-- 其他属性设置... -->
</bean>

如果同时有多个属性要设置,在value中通过分号分隔。其他数据库的设置方式参见资料3。

 
超时捕获
在Transaction timeout设置生效的情况下,发生超时后,框架将主动回滚当前事务并抛出UncategorizedSQLException。这是一个RuntimeException的子类,通过其getSql()或getMessage()方法可以得知引发超时的sql语句。
在使用JDBC Driver Socket阻塞超设置时,发生超时后,当前连接将被driver关闭,事务中正在执行的操作,不论是通过JdbcTemplate还是其他ORM框架执行的,都将引发SQLException(异常信息为:关闭的连接),这个异常将被上层的TransactionInterceptor捕获并被重新包装成一个UncategorizedSQLException的实例,随后回滚事务,但由于连接已关闭,因此又会引发回滚异常,所以会看到

“TransactionInterceptor.completeTransactionAfterThrowing (TransactionAspectSupport.java:414)

Application exception overridden by rollback exception ”
最终,会向调用者抛出一个TransactionSystemException的实例,通过其getApplicationException()方法可以获得被覆盖前的那个UncategorizedSQLException的实例。
 
参考资料
1. Understanding JDBC Internals & Timeout Configuration
2. Spring transaction timeout doesn't work?
3. Spring事务超时时间可能存在的错误认识
4. Using Spring 3 with Mybatis 3 Tutorial – part 1

在Spring中基于JDBC进行数据访问时如何控制超时的更多相关文章

  1. 【转】在Spring中基于JDBC进行数据访问时怎么控制超时

    http://www.myexception.cn/database/1651797.html 在Spring中基于JDBC进行数据访问时如何控制超时 超时分类 超时根据作用域可做如下层级划分: Tr ...

  2. Spring中的JDBC API

    1 JdbcTemplate的诞生 JDBC作为Java平台访问关系数据库的标准API,其成功是有目共睹的.为了避免在JDBC API在使用中的种种尴尬局面(几乎程式一样的代码,繁琐的异常处理),Sp ...

  3. Spring中使用JDBC

    Spring中的数据库异常体系 使用JDBC(不使用Spring)的时候,我们需要强制捕获SQLException,否则无法使用JDBC处理任何事情.SQLException表示尝试访问数据库的时候出 ...

  4. spring框架总结(04)----介绍的是Spring中的JDBC模板

    1.1  Jdbc模板概述 它是spring框架中提供的一个对象,是对原始Jdbc API对象的简单封装.spring框架为我们提供了很多的操作模板类,入下图所示: 我们今天的主角在spring-jd ...

  5. Spring框架学习(3)spring中使用jdbc

    内容源自:spring中使用jdbc spring dao层中对jdbc进行了封装,使用模板模式的设计模式,通过ioc被动注入的方式将jdbcTemplate这个模板类注入到数据对象中,进行数据库操作 ...

  6. 【原创】打造基于Dapper的数据访问层

    [原创]打造基于Dapper的数据访问层   前言 闲来无事,花几天功夫将之前项目里用到的一个数据访问层整理了出来.实现单个实体的增删改查,可执行存储过程,可输出返回参数,查询结果集可根据实际情况返回 ...

  7. Spring中基于xml的AOP

    1.Aop 全程是Aspect Oriented Programming 即面向切面编程,通过预编译方式和运行期动态代理实现程序功能的同一维护的一种技术.Aop是oop的延续,是软件开发中的 一个热点 ...

  8. Spring 框架的概述以及Spring中基于XML的IOC配置

    Spring 框架的概述以及Spring中基于XML的IOC配置 一.简介 Spring的两大核心:IOC(DI)与AOP,IOC是反转控制,DI依赖注入 特点:轻量级.依赖注入.面向切面编程.容器. ...

  9. 在Spring中配置jdbc为什么不能用${username}问题

    楼主在spring中配置jdbc时,引用的是dbcp.jar包,在dataSource.properties配置文件中,有mysql用户名,楼主自然的选择了使用username,密码是root, 然后 ...

随机推荐

  1. ALBB 找公共最长连续字母序列的长度

    问题描写叙述 给定一个 query 和一个 text .均由小写字母组成.要求在 text 中找出以相同的顺序连续出如今 query 中的最长连续字母序列的长度. 比如, query为"ac ...

  2. vue install 注册组件

    1.myPlugin.js文件 let MyPlugin = {}; MyPlugin.install = function (Vue, options) { // 1. 添加全局方法或属性 Vue. ...

  3. SharePoint 2013 对话框

    The quick way to open a sharepoint 2013 dialog modal form is via Javascript below 1 2 3 4 5 function ...

  4. Linux Sed命令具体解释+怎样替换换行符&quot;\n&quot;(非常多面试问道)

    Sed Sed是一个强大的文本处理工具 能够採用正则匹配.对文本进行插入删除改动等操作 Sed处理的时候,一次处理一行,每一次把当前处理的存放在暂时缓冲区.处理完后输出缓冲区内容到屏幕,然后把下一行读 ...

  5. sqlserver中的时间比较

    例子: select count(*) from table where DATEDIFF ([second], '2004-09-18 00:00:18', '2004-09-18 00:00:19 ...

  6. HDFS源码分析心跳汇报之DataNode注册

    HDFS源码分析心跳汇报之DataNode注册,近期推出!

  7. 深度解析 | 秒懂AI+智慧手机实践

    阅读数:17 ​​​随着人工智能的概念越来越深入人心,智慧化生活和对应的智慧化终端体验也吸引越来越多的目光.可以想见,人工智能会深刻改变终端产业,但目前也面临各种挑战和问题.此前,在南京软件大会上,华 ...

  8. 【虚拟机】WIN8.1系统虚拟机完全彻底删除

    一.首先删除注册表 用管理员身份打开CMD,输入F:\>VMware-workstation-full-12.5.5-5234757.exe/clean,根据自己的虚拟机安装文件的路径进行改变( ...

  9. pm2 服务崩溃 Error: bind EADDRINUSE

    pm2 服务崩溃 Error: bind EADDRINUSE  发布于 1 年前  作者 zhujun24  2444 次浏览  来自 问答 Error: bind EADDRINUSE 0.0.0 ...

  10. TP 自动验证规则

    #自动验证 protected $_validate=array( #参数最后代表1 表示必须验证,0表示当这个字段存在的时候验证 array('username','require','账号不能为空 ...