环境是springboot和mybatis,事务配置用的是spring默认的。
我通过controller层调用service1的方法,然后在service1的方法里面调用service2的方法,当service2的方法正常执行成功后,service1的方法还没有结束,继续往下执行,此时service1方法抛出异常,经过多次尝试,发现service1的事务回滚了,而service2事务没有回滚
service1代码如下:
@Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
public void startWorkflowByKey() {
//service1调用service2方法
service2.startWorkflowByKey();
//service1修改数据
mapper.updateLeaveAll(leave);
/*try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}*/
//抛出异常
if(true){
throw new RuntimeException();
}
}
service2代码如下:
@Service
public class WorkflowServiceImpl implements WorkflowService {
@Autowired
private RuntimeService runtimeService;
@Autowired
private HistoryService historyService;
@Autowired
private TaskService taskService;
@Autowired
private IdentityService identityService;
@Autowired
private RepositoryService repositoryService;
@Override
@Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
public ProcessInstance startWorkflowByKey() {
runtimeService.startProcessInstanceByKey();
return instance;
}
}
我让service1线程休眠5秒钟,service1的事务在5秒内没有提交,此时去页面查询,发现service2方法执行完后,事务已经提交了,service2上我加了Propagation.REQUIRED,应该是加入service1的事务才对,但是service2的事务却自己提交了。
因此这两个service使用的肯定不是同一个事务控制器,于是检查springboot的配置:
@Bean
public SpringProcessEngineConfiguration springProcessEngineConfiguration(MasterDataSource dataSource, DataSourceTransactionManager transactionManager){
SpringProcessEngineConfiguration spec = new SpringProcessEngineConfiguration();
spec.setDataSource(dataSource);
这里将datasource放入transactionManager中,事务就生效了
transactionManager.setDataSource(dataSource);
spec.setTransactionManager(transactionManager);
//解决流程png中文乱码
spec.setActivityFontName("宋体");
spec.setLabelFontName("宋体");
//spec.set
//若表不存在,自动新建表
spec.setDatabaseSchemaUpdate("true");
Resource[] resources = null;
// 自动部署静态bpmn文件
try {
resources = new PathMatchingResourcePatternResolver().getResources("classpath*:processes/*.bpmn");
} catch (IOException e) {
e.printStackTrace();
}
spec.setDeploymentResources(resources);
return spec;
}