目的
有2个不同的数据源,在同一个service中使用,失败时事务同时回滚。
一个方法不能有2个事务注解,我拆成了2个,报错了
org.springframework.transaction.NoTransactionException:
No transaction aspect-managed TransactionStatus in scope
错误实现
@Transactional(transactionManager = "transactionManagerSecond",rollbackFor = Exception.class)
public boolean updateImportMetaData(MetaData base,MetaData partMeta,LayerEntity layerEntity){
gpMetaDataDao.saveAndFlush(base);
if(partMeta!=null){
gpMetaDataDao.saveAndFlush(partMeta);
}
boolean b = metaDataTool.updatePgMeta(layerEntity);
if(!b){
//如果pg更新失败(它回滚了) 则gp也回滚
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
//就是这里报错了,回滚失败,提示当前没有事务
return false;
}
return true;
}
@Transactional(transactionManager = "transactionManagerPrimary",rollbackFor = Exception.class)
public boolean updatePgMeta(LayerEntity layerEntity){
try {
int[] l=new int[]{
1,2};
int th=l[3];//制造异常
layerInfoDao.saveAndFlush(layerEntity);
}catch (Exception e){
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}
return true;
}
错误原因
网上搜的解释是 同一个类里面只能搞一个事务,这2个数据源的事务需要放在不同的类里。于是我把一个数据源的事务方法放在了别的类中。然后在service方法中调用metaDataTool.updatePgMeta()
pulic class MetaDataTool{
@Transactional(transactionManager = "transactionManagerPrimary",rollbackFor = Exception.class)
public boolean updatePgMeta(LayerEntity layerEntity){
try {
int[] l=new int[]{
1,2};
int th=l[3];
layerInfoDao.saveAndFlush(layerEntity);
}catch (Exception e){
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return false;
}
return true;
}
}
再测试,结果
还是那个错,不靠谱!又搜到有人说一个服务一个事务,一次请求一个事务。我一次请求2个事务真的不行吗?
再修改
不使用try catch手动回滚,让它出异常自动回滚。还是不行。
终极解决方案
使用jta-atomikos分布式事务
点此查看