How to force transaction commit in Spring Boot test?

老子叫甜甜 提交于 2020-02-04 03:23:08

问题


How can I force a transaction commit in Spring Boot (with Spring Data) while running a method and not after the method ?

I've read here that it should be possible with @Transactional(propagation = Propagation.REQUIRES_NEW) in another class but doesn't work for me.

Any hints? I'm using Spring Boot v1.5.2.RELEASE.

@RunWith(SpringRunner.class)
@SpringBootTest
public class CommitTest {

    @Autowired
    TestRepo repo;

    @Transactional
    @Commit
    @Test
    public void testCommit() {
        repo.createPerson();
        System.out.println("I want a commit here!");
        // ...
        System.out.println("Something after the commit...");
    }
}

@Repository
public class TestRepo {

    @Autowired
    private PersonRepository personRepo;

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void createPerson() {
        personRepo.save(new Person("test"));
    }
}

回答1:


An approach would be to inject the TransactionTemplate in the test class, remove the @Transactional and @Commit and modify the test method to something like:

...
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...");
    }

Or

new TransactionCallback<Person>() {

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

    // ...
});

instead of the TransactionCallbackWithoutResult callback impl if you plan to add assertions to the person object that was just persisted.




回答2:


Solutions with 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;
    });
}

use as

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

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


来源:https://stackoverflow.com/questions/44079793/how-to-force-transaction-commit-in-spring-boot-test

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!