How to rollback nested transactions with Propagation.REQUIRES_NEW in integration tests

后端 未结 2 889
挽巷
挽巷 2021-02-02 11:43

I have several integration tests for various services that extend the following baseclass:

@ContextConfiguration(locations=\"classpath:applicationContext-test.xm         


        
2条回答
  •  不思量自难忘°
    2021-02-02 12:37

    I added comment to Spring improvement ticket on this. I'll copy it here too:

    I worked around this problem by converting all service methods that were declaratively setup like this

    @Transactional(propagation = REQUIRES_NEW)
    public Object doSmth() {
      // doSmthThatRequiresNewTx
    }
    

    to use TransactionTemplate instead:

    private TransactionTemplate transactionTemplate;
    
    public Object doSmth() {
      return transactionTemplate.execute(new TransactionCallback() {
                @Override
                public Object doInTransaction(TransactionStatus status) {
                    // doSmthThatRequiresNewTx
                }
            });
      }
    
    
    

    Under tests I configure transactionTemplate's propagation behavior to be PROPAGATION_REQUIRED, under real app I configure transactionTemplate's propagation behaviour to be PROPAGATION_REQUIRES_NEW. It works as expected. The limitation of this workaround is that under tests it is not possible to assert the fact that inner transaction is not rolledback in an exceptional scenario.

    The other solution would be to explicitly delete everything doSmth() does in the database in the @AfterTransaction method in test. That 'delete' SQL will be run in the new transaction, as its results would be otherwise rolled back routinely by Spring's TransactionConfiguration default behaviour.

    提交回复
    热议问题