2016-03-01 100 views
0

問題:春:手動回滾JPA交易

  • 我希望衝突在內存中的數據與一個存儲在SQL表中設置。
  • 該比賽是在多個欄目上進行的。
  • 內存集可能相當大〜10000條記錄。
  • 我不想堅持內存集。
  • 我使用Spring和JPA
  • 多個請求可以同時做

我嘗試的解決方案

  • 開始交易
  • 寫請求的記錄爲 「臨時」 表
  • 通過加入兩張表選擇所需的結果
  • Rollbac k爲交易

(或SQL術語)

CREATE TABLE player_details (
    firstname VARCHAR2(10), 
    surname VARCHAR2(10), 
    position VARCHAR2(2) 
); 

CREATE TABLE player_request (
    firstname VARCHAR2(10), 
    surname VARCHAR2(10) 
); 

INSERT INTO player_details (firstname, surname, position) VALUES ('Scottie', 'Pippen', 'SF'); 
INSERT INTO player_details (firstname, surname, position) VALUES ('Michael', 'Jordan', 'SG'); 
INSERT INTO player_details (firstname, surname, position) VALUES ('Dennis', 'Rodman', 'PF'); 

START TRANSACTION; 

    INSERT INTO player_request (firstname, surname) VALUES ('Scottie', 'Pippen'); 
    INSERT INTO player_request (firstname, surname) VALUES ('Michael', 'Jordan'); 

    SELECT 
    d.* 
    FROM player_details d 
    JOIN player_request r 
    ON d.firstname = r.firstname 
    AND d.surname = r.surname; 

ROLLBACK; 

SELECT 
    COUNT(*) AS player_requests 
FROM family; 

給出:

FIRSTNAME SURNAME POSITION 
---------- ---------- -------- 
Scottie Pippen  SF  
Michael Jordan  SG  

PLAYER_REQUESTS 
--------------- 
       0 

不過,我不能找到一個辦法讓Spring來回滾事務。我嘗試了幾種不同的註釋和方法,但沒有找到一個可行的方法。有一個嗎?

(最壞的情況下,我只是給它一個請求ID,然後提交刪除)

+0

你的輸出究竟有什麼問題? – Yossi

+1

你能發佈一些你的代碼片段嗎?現在我相信'entityManager.getTransaction()。setRollbackOnly()'可能就是你所需要的,因爲'entityManager'是由Spring注入的 –

+0

這是,但我不認爲Spring會讚賞你搞砸了它。如果我包含該代碼,則會出現以下錯誤:'不允許在共享EntityManager上創建事務 - 使用Spring事務或EJB CMT' –

回答

0

明白了。

這是行不通的:

@Transactional 
public MatchResponse myMatcherMethod(MatchCriteria criteria) { 
    TransactionStatus transactionStatus = TransactionAspectSupport.currentTransactionStatus(); 
    transactionStatus.setRollbackOnly(); 
    saveMatchCriteria(criteria); 

    MatchResponse matches = getMatches(); 
    return matches; 
} 

有人給我任何比賽。托馬斯問我後我的代碼(感謝+1!),所以我決定,我想補充一些額外的線條表明該標準並沒有被保存:

@Transactional 
public MatchResponse myMatcherMethod(MatchCriteria criteria) { 
    TransactionStatus transactionStatus = TransactionAspectSupport.currentTransactionStatus(); 
    transactionStatus.setRollbackOnly(); 
    saveMatchCriteria(criteria); 

    //Added these lines: 
    MatchCriteria savedCriteria = getMatchCriteria(); 
    System.out.println("# of criteria: " + savedCriteria.getIdentifiers().size()); 

    MatchResponse matches = getMatches(); 
    return matches; 
} 

..但在這一點上它開始工作!

所以我猜測我的測試查詢造成了沖水。所以我嘗試過:

@Transactional 
public MatchResponse myMatcherMethod(MatchCriteria criteria) { 
    TransactionStatus transactionStatus = TransactionAspectSupport.currentTransactionStatus(); 
    transactionStatus.setRollbackOnly(); 
    saveMatchCriteria(criteria); 

    // Replaced with: 
    transactionStatus.flush(); 

    MatchResponse matches = getMatches(); 
    return matches; 
} 

..它的工作。

這在事後看來很明顯:

  • Repository.save - > JVM內存
  • 的flush() - >運行插入語句
  • 結束交易 - >提交

看起來像我需要刷新我的JPA生命週期!