2016-03-01 103 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生命周期!