为了解决这个问题, 网上找了很多资料。
但是你懂得, 百度搜出来的都是同一个问题拷贝来拷贝去。
什么public方法,unchecked异常都试过了还是不行。
后来在谷歌上找到一个blog
https://ameblo.jp/kochablo/entry-11578714824.html
大致意思是, @Transactional必须是利用通过DI注入完后的对象调用@Transactional注释的方法。
也就是
问题代码
// ServiceA代码
public class ServiceA {
public void insert() {
insertTbl1();
insertTbl2();
//...
//......
}
@Transactional
public void insertTbl1() {
// do something.
}
@Transactional
public void insertTbl2() {
// do something.
}
}
// ServiceB代码
public class ServiceB {
@Autowired
ServiceA serviceA;
public void test() {
serviceA.insert();
}
}
需要改成如下
// ServiceA代码
public class ServiceA {
// 在ServiceB当中直接通过DI后的对象调用insert,
// 所以这个方法上必须要有Transactional,否则不会启动事务。
@Transactional
public void insert() {
insertTbl1();
insertTbl2();
//...
//......
}
@Transactional(propagation = Propagation.REQUIRED)
public void insertTbl1() {
// do something.
}
@Transactional(propagation = Propagation.REQUIRED)
public void insertTbl2() {
// do something.
}
}
// ServiceB代码
public class ServiceB {
@Autowired
ServiceA serviceA;
public void test() {
// ServiceA的insert方法必须要@Transactional。
serviceA.insert();
}
}
Why?
https://dev.classmethod.jp/server-side/declarative-trasaction-by-spring-aop/
另外也可以通过代码写上事务管理也可以。
@Autowired
PlatformTransactionManager txManager;
// 使用DefaultTransactionDefinition
public void insert1() {
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
TransactionStatus status = txManager.getTransaction(def);
try {
// do some thing..
txManager.commit(status);
} finally {
if (!status.isCompleted()) txManager.rollback();
}
}
// 使用template
public void insert2() {
TransactionTemplate template = new TransactionTemplate(txManager);
template.setName("tx name");
template.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
template.execute(status -> {
// do something...
return "result";
});
}