我正在使用 Spring Boot。我可以使用@Transactional一個方法來強制事務。有時我需要某種方法來使用兩個或多個事務。
天真的方法行不通:
public void doActions() {
doAction1();
doAction2();
}
@Transactional
void doAction1() { ... }
@Transactional
void doAction2() { ... }
因為 Spring 使用代理來實作事務。
通常我使用以下方法:
@Autowired
private ThisService self;
public void doActions() {
self.doAction1();
self.doAction2();
}
@Transactional
void doAction1() { ... }
@Transactional
void doAction2() { ... }
它起作用了,但是在 Spring 2.6.0 中,這種回圈依賴會導致應用程式無法以可怕的錯誤啟動,除非我將 spring.main.allow-circular-references 設定為 true。
我真的不明白回圈參考不好的原因。但顯然 Spring Boot 開發人員想要阻止這種設計,所以,我想,我最好聽從他們的建議。
另一種方法是使用事務管理器并以編程方式呼叫事務 api:
@Autowired
private TransactionTemplate transactionTemplate;
public void doActions() {
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(@NonNull TransactionStatus status) {
doAction1();
}
});
transactionTemplate.execute(status -> {
doAction2();
return null;
});
它有效,但在我看來它有點冗長和丑陋。
還有其他我錯過的方法嗎?我應該將 spring.main.allow-circular-references 設定為 true 嗎?恐怕開發人員將來會使這些回圈參考不受支持,因此我需要重新設計我的應用程式。
uj5u.com熱心網友回復:
是的。我同意這很丑。您可以創建一個只負責在事務中執行某些代碼的服務。相同的想法,TransactionTemplate但它用于@Transational管理事務。
@Service
public class TransactionExecutor {
@Transactional(propagation = Propagation.REQUIRED)
public <T> T execute(Supplier<T> action) {
return action.get();
}
@Transactional(propagation = Propagation.REQUIRED)
public void execute(Runnable action) {
action.run();
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public <T> T executeInNewTx(Supplier<T> action) {
return action.get();
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void executeInNewTx(Runnable action) {
action.run();
}
}
然后注入它來使用它:
@Service
public class FooService {
@Autowired
private TransactionExecutor txExecutor;
public void doActions() {
txExecutor.execute(()->doAction1());
txExecutor.execute(()->doAction2());
}
void doAction1() { ... }
void doAction2() { ... }
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/414770.html
標籤:
