如何在Spring Boot测试中强制执行事务提交?

时间:2017-05-19 22:23:58

标签: java spring-boot transactions spring-data spring-data-jpa

如何在Spring Boot(使用Spring Data)强制事务提交,同时运行方法

我在这里读过,在{+ 1}}的另一个课程中应该可以这样做,但对我来说不起作用。

任何提示?我使用的是Spring Boot v1.5.2.RELEASE。

@Transactional(propagation = Propagation.REQUIRES_NEW)

3 个答案:

答案 0 :(得分:9)

使用帮助程序类org.springframework.test.context.transaction.TestTransaction(从Spring 4.1开始)。

默认情况下,测试会回滚。真正犯一个需要做的事

// do something before the commit 

TestTransaction.flagForCommit(); // need this, otherwise the next line does a rollback
TestTransaction.end();
TestTransaction.start();

// do something in new transaction

请不要在测试方法上使用@Transactional!如果您忘记了使用业务代码进行交易,则@Transactional测试将永远不会检测到它。

答案 1 :(得分:4)

一种方法是在测试类中注入TransactionTemplate,删除@Transactional@Commit并将测试方法修改为:

...
public class CommitTest {

    @Autowired
    TestRepo repo;

    @Autowired
    TransactionTemplate txTemplate;

    @Test
    public void testCommit() {
        txTemplate.execute(new TransactionCallbackWithoutResult() {

          @Override
          protected void doInTransactionWithoutResult(TransactionStatus status) {
            repo.createPerson();
            // ...
          }
        });

        // ...
        System.out.println("Something after the commit...");
    }

或者

new TransactionCallback<Person>() {

    @Override
    public Person doInTransaction(TransactionStatus status) {
      // ...
      return person
    }

    // ...
});
如果您打算将断言添加到刚刚持久存在的person对象,请使用

而不是TransactionCallbackWithoutResult回调impl。

答案 2 :(得分:1)

lambdas解决方案。

@Autowired
TestRepo repo;

@Autowired
TransactionTemplate txTemplate;

private <T> T doInTransaction(Supplier<T> operation) {
    return txTemplate.execute(status -> operation.get());
}

private void doInTransaction(Runnable operation) {
    txTemplate.execute(status -> {
        operation.run();
        return null;
    });
}

用作

Person saved = doInTransaction(() -> repo.save(buildPerson(...)));

doInTransaction(() -> repo.delete(person));