@Transactional事务之timeout属性失效解决思路

背景:生产环境出现写成功,接口却返回失败的场景

分析:先确认是否如他们反馈的现象一致,查询日志确认一致;接口进入和返回失败的时间间隔发现是5秒,与设置的接口超时时间一致,分析大概率是超时了,内部具体日志分析,定位到入库的事务执行耗时6秒多;查看代码,事务没有设置超时时间,默认不超时或根据数据库默认设置,经后期测试为是不超时;当事务超过接口超时时间后,接口直接返回超时失败,但是事务并没有结束,而是等待竞争锁资源,获取到锁后继续执行,并且入库成功;从而赵成接口返回失败,实际入库成功的不一致现象;

解决办法:设置超时时间

1.spring的声明式事务:

@Transactional(rollbackFor = Exception.class, timeout = 3)

2.编程式事务

//开启事务
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
// 事物隔离级别,开启新事务
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
// 事务超时时间(秒)
def.setTimeout(3);
// 获得事务状态
TransactionStatus status = transactionManager.getTransaction(def);
try {
  ...
  //提交事务
  transactionManager.commit(status);
  log.info("成功");
} catch (TransactionTimedOutException e){
    transactionManager.rollback(status);
    log.error("超时异常:", e);
} catch (Exception e) {
    transactionManager.rollback(status);
    log.error("异常:", e);
}

好记性不如烂笔头!

你可能感兴趣的:(事务,java,spring,开发语言)