爲了解決這個問題, 網上找了很多資料。
但是你懂得, 百度搜出來的都是同一個問題拷貝來拷貝去。
什麼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";
});
}