簡體   English   中英

如何將Spring事務傳播到另一個線程?

[英]How to propagate Spring transaction to another thread?

也許,我做錯了什么,但我找不到適合下列情況的好方法。

我想對使用下面的Spring Batch執行作業的服務進行單元測試。 作業通過預先配置的AsyncTaskExecutor在單獨的線程中執行。 在我的單元測試中,我想:

  1. 創建幾個域對象並通過DAO保留它們
  2. 調用服務方法以啟動作業
  3. 等到作業完成
  4. 使用DAO檢索域對象並檢查其狀態

顯然,以上所有內容都應該在一個事務中執行,但不幸的是, 事務不會傳播到新線程 (我理解這背后的基本原理)。

我想到的想法:

  • 在步驟(1)之后提交事務#1。 不好,因為在單元測試后應該回滾DB狀態。
  • 在作業配置中使用Isolation.READ_UNCOMMITTED 但這需要兩種不同的配置用於測試和生產。

雖然這不是您問題的真正解決方案,但我發現可以手動在工作線程中啟動事務。 在某些情況下,這可能就足夠了。

資料來源: Spring程序化交易

例:

@PersistenceContext
private EntityManager entityManager;
@Autowired
private PlatformTransactionManager txManager;

/* in a worker thread... */
public void run() {
    TransactionStatus tx = txManager.getTransaction(new DefaultTransactionDefinition());
    try {
        entityManager.find(...)
        ...
        entityManager.flush(...)
        etc...
        txManager.commit(tx);
    } catch (RuntimeException e) {
        txManager.rollback(tx);
    }
}

我認為最簡單的解決方案是在測試執行期間使用SyncTaskExecutor配置JobLauncher - 這樣作業在與測試相同的線程中執行並共享事務。

任務執行程序配置可以移動到單獨的spring配置xml文件中。 有兩個版本 - 一個是在測試期間使用的SyncTaskExecutor,另一個是用於生產運行的AsyncTaskExecutor。

如果您確實需要單獨的配置,我建議您在配置中模板化隔離策略,並從屬性文件中獲取其值,這樣您就不會使用一組不同的Spring配置進行測試和生成。

但我同意使用相同的政策生產用途是最好的。 您的燈具數據有多大,以及有一個setUp()步驟可以吹走並重建您的數據(可能來自快照,如果它是大量數據)有多么糟糕,這樣您就不必依賴回滾?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM