最近在项目中会使用到多数据源,数据源太多了,所以采用的配置DataSource的方式,然后代码中使用JdbcTempate(dataSource)
的方式。但是最近遇到一个问题,在使用jt.batchUpdate(sqls)
时,发现如果有sql
有误,jdbctempalte
并不会回滚。由于代码框架很老,不再适合对每个数据源都配置DataSourceTransactionManager
。最终在网上看见下面的方法,纪录一下:
public static void batchExecute(JdbcTemplate jt, List<String> sqlList) throws SQLException{
if(sqlList.size() == 0) return;
DefaultTransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
DataSourceTransactionManager dm = new DataSourceTransactionManager(jt.getDataSource());
TransactionStatus tmp = dm.getTransaction(transactionDefinition);
String[] sqls = new String[sqlList.size()];
sqlList.toArray(sqls);
try{
jt.batchUpdate(sqls);
dm.commit(tmp);
} catch (Exception e) {
dm.rollback(tmp);
throw new SQLException(e.getMessage());
}
}
注意
由于spring的事务处理是按照 LIFO/stack behavior的方式进行的,所以在多个事务进行提交时必须按照上述规则进行,否则就会报上面异常
当你写了多个数据源事务时要遵循后进先出
。否则会报出下面的错误
spring tranaction: Cannot deactivate transaction synchronization - not active
修改后代码
try{
jt.batchUpdate(sqls);
jt2.batchUpdate(sqls2);
dm2.commit(tmp2);
dm.commit(tmp);
} catch (Exception e) {
dm.rollback(tmp);
dm2.rollback(tmp2);
}
网友评论