如果想在spring操作事務(wù)結(jié)束后執(zhí)行一些代碼,應(yīng)該怎么辦? 為什么要這樣?比如我們在事務(wù)中給其他系統(tǒng)發(fā)了消息,期望事務(wù)提交后過一會(huì)收到這個(gè)系統(tǒng)的回應(yīng),然后操作剛剛提交的數(shù)據(jù)。但是如果回應(yīng)來的太快就像龍卷風(fēng),我們的事務(wù)是托管給Spring的可能還沒提交,也就沒法操作了 一個(gè)方案是使用 Applica
在Spring中,如果需要在事務(wù)操作結(jié)束后執(zhí)行一些代碼,可以采取哪些方法呢?
為什么需要這樣做呢?比如,在事務(wù)中向其他系統(tǒng)發(fā)送消息,希望在事務(wù)提交后一段時(shí)間內(nèi)收到該系統(tǒng)的響應(yīng),然后對剛剛提交的數(shù)據(jù)進(jìn)行操作。但是如果響應(yīng)太快,就像龍卷風(fēng)一樣,我們的事務(wù)可能還沒有提交,這樣就無法進(jìn)行操作。
一種解決方案是使用
ApplicationEventPublisher
,可以參考之前的博客:
https://www.iteye.com/blog/somefuture-2405963
博客訪問量超過100萬,我們假設(shè)總訪問量是10倍哈哈
這個(gè)API是Spring 1就提供的。從Spring 5開始,提供了一個(gè)新的事務(wù)相關(guān)的API,叫
TransactionSynchronization
事務(wù)同步機(jī)制。
首先編寫一個(gè)Bean實(shí)現(xiàn)
TransactionSynchronization
接口
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.stereotype.Component;
@Component
public class AfterTransactionCommitExecutor implements TransactionSynchronization {
@Override
public void afterCommit() {
// 事務(wù)提交后執(zhí)行的操作
System.out.println("事務(wù)已提交,執(zhí)行后續(xù)操作");
}
// 其他需要重寫的方法...
public void registerSynchronization() {
// 注冊當(dāng)前實(shí)例到事務(wù)同步管理器
TransactionSynchronizationManager.registerSynchronization(this);
}
}
然后,在服務(wù)層或者合適的地方調(diào)用
registerSynchronization()
方法來注冊事務(wù)同步回調(diào)
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class SomeService {
@Autowired
private AfterTransactionCommitExecutor afterTransactionCommitExecutor;
@Transactional
public void doWork() {
// 業(yè)務(wù)邏輯...
// 注冊事務(wù)同步回調(diào)
afterTransactionCommitExecutor.registerSynchronization();
}
}
基本上使用它還是為了操作數(shù)據(jù),所以需要把參數(shù)傳給他。
最簡單的方法是添加一個(gè)成員屬性。
@Component
public class AfterTransactionCommitExecutor extends TransactionSynchronizationAdapter {
private Object parameter;
@Override
public void afterCommit() {
// 事務(wù)提交后使用參數(shù)執(zhí)行操作
doSomethingWithParameter(parameter);
}
public void setParameter(Object parameter) {
this.parameter = parameter;
}
private void doSomethingWithParameter(Object parameter) {
}
public void registerSynchronization() {
TransactionSynchronizationManager.registerSynchronization(this);
}
}
@Service
public class SomeService {
@Autowired
private AfterTransactionCommitExecutor afterTransactionCommitExecutor;
@Transactional
public void doWork(Object parameter) {
// 設(shè)置參數(shù)
afterTransactionCommitExecutor.setParameter(parameter);
// 注冊事務(wù)同步回調(diào)
afterTransactionCommitExecutor.registerSynchronization();
}
}
@Service
public class SomeService {
@Transactional
public void doWork(final Object parameter) {
// 業(yè)務(wù)邏輯...
// 注冊事務(wù)同步回調(diào)并傳遞參數(shù)
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
@Override
public void afterCommit() {
doSomethingWithParameter(parameter);
}
});
}
private void doSomethingWithParameter(Object parameter) {
// 使用參數(shù)執(zhí)行相關(guān)操作
}
}
需要注意的是,使用成員變量傳遞參數(shù)時(shí),如果多個(gè)事務(wù)并發(fā)執(zhí)行,可能會(huì)存在線程安全問題。為了避免這個(gè)問題,可以使用ThreadLocal來存儲(chǔ)參數(shù),或者在事務(wù)方法中每次都創(chuàng)建一個(gè)新的TransactionSynchronization實(shí)例。
小編推薦閱讀機(jī)器學(xué)習(xí):神經(jīng)網(wǎng)絡(luò)構(gòu)建(下)
閱讀華為Mate品牌盛典:HarmonyOS NEXT加持下游戲性能得到充分釋放
閱讀實(shí)現(xiàn)對象集合與DataTable的相互轉(zhuǎn)換
閱讀鴻蒙NEXT元服務(wù):論如何免費(fèi)快速上架作品
閱讀算法與數(shù)據(jù)結(jié)構(gòu) 1 - 模擬
閱讀5. Spring Cloud OpenFeign 聲明式 WebService 客戶端的超詳細(xì)使用
閱讀Java代理模式:靜態(tài)代理和動(dòng)態(tài)代理的對比分析
閱讀Win11筆記本“自動(dòng)管理應(yīng)用的顏色”顯示規(guī)則
閱讀本站所有軟件,都由網(wǎng)友上傳,如有侵犯你的版權(quán),請發(fā)郵件[email protected]
湘ICP備2022002427號-10 湘公網(wǎng)安備:43070202000427號© 2013~2025 haote.com 好特網(wǎng)