Spring:手动回滚JPA事务

时间:2016-03-01 16:20:43

标签: sql spring jpa transactional

问题:

  • 我想用内存在SQL表中的内存数据集进行冲突。
  • 匹配在多个列上进行。
  • 内存集可能非常大~10000条记录。
  • 我不想坚持内存设置。
  • 我使用的是Spring和JPA
  • 可以同时发出多个请求

我的尝试解决方案

  • 开始交易
  • 将请求的记录写入"临时"表
  • 通过加入两个表
  • 选择所需的结果
  • 回滚交易

(或用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,提交然后删除)

1 个答案:

答案 0 :(得分:0)

知道了。

这不起作用:

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

    MatchResponse matches = getMatches();
    return matches;
}

它没有给我任何比赛。 Tomas让我发布我的代码(谢谢!+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生命周期!