如何在Spring Boot(使用Spring Data)强制事务提交,同时运行方法和不?
我在这里读过,在{+ 1}}的另一个课程中应该可以这样做,但对我来说不起作用。
任何提示?我使用的是Spring Boot v1.5.2.RELEASE。
@Transactional(propagation = Propagation.REQUIRES_NEW)
答案 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));