原文:https://jinnianshilongnian.iteye.com/blog/1986023
以下内容是原文截取的结论。不明白的看原文吧。
例子:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring-config.xml")
@TransactionConfiguration(transactionManager = "txManager", defaultRollback = false)
@Transactional(timeout = 2)
public class Timeout1Test {
@Autowired
private DataSource ds;
@Test
public void testTimeout() throws InterruptedException {
System.out.println(System.currentTimeMillis());
JdbcTemplate jdbcTemplate = new JdbcTemplate(ds);
jdbcTemplate.execute(" update test set name = name || '1'");
System.out.println(System.currentTimeMillis());
Thread.sleep(3000L);
}
}
我设置事务超时时间是2秒;但我事务肯定执行3秒以上;为什么没有起作用呢? 这其实是对Spring实现的事务超时的错误认识。那首先分析下Spring事务超时实现吧。
2、分析
省略,感兴趣的,请移步原文https://jinnianshilongnian.iteye.com/blog/1986023
3、结论
写道
Spring事务超时 = 事务开始时到最后一个Statement创建时时间 + 最后一个Statement的执行时超时时间(即其queryTimeout)。
补充:
本例中,采用的是jdbc事物(org.springframework.jdbc.datasource.DataSourceTransactionManager)
所以,“总时长”是从方法开始,到执行完 jdbcTemplate.execute()方法截至。而不是到方法最后!!!!!!
4、因此
假设事务超时时间设置为2秒;假设sql执行时间为1秒;
如下调用是事务不超时的:
- public void testTimeout() throws InterruptedException {
- System.out.println(System.currentTimeMillis());
- JdbcTemplate jdbcTemplate = new JdbcTemplate(ds);
- jdbcTemplate.execute(" update test set hobby = hobby || '1'");
- System.out.println(System.currentTimeMillis());
- Thread.sleep(3000L);
- }
而如下事务是超时的:
- public void testTimeout() throws InterruptedException {
- Thread.sleep(3000L);
- System.out.println(System.currentTimeMillis());
- JdbcTemplate jdbcTemplate = new JdbcTemplate(ds);
- jdbcTemplate.execute(" update test set hobby = hobby || '1'");
- System.out.println(System.currentTimeMillis());
- }
因此,不要忽略应用中如远程调用产生的事务时间和这个事务时间是否对您的事务产生影响。