不要理解Spring中嵌套事务的行为

时间:2016-01-22 17:39:02

标签: spring neo4j spring-data spring-data-neo4j spring-data-neo4j-4

我的数据库有触发器。它们在创建实体后触发。我想测试一个条件,这取决于触发器执行的结果。所以,我需要能够在我的测试中看到这些结果。但触发器将在提交后触发,此时事务将实际回滚。

看来,我需要使用transactionTemplatePROPAGATION_REQUIRES_NEW创建新的交易。我试过这种方式,我能够看到触发器执行的结果(horray!)。但这种方式会产生另一个问题:查看代码,我试图通过评论解释一个奇怪的行为。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {TestConfiguration.class})
@Transactional
public class ServiceTest {

    @Inject
    private PlatformTransactionManager txManager;

    <...>

    @Before
    public final void setUp() {
        clearDatabase();
    }

    @Test
    public final void testFilter() {
        // Note: here database is empty - was cleared by setUp() method
        TransactionTemplate tt = new TransactionTemplate(txManager);
        tt.setPropagationBehavior(PROPAGATION_REQUIRES_NEW);
        tt.execute(new TransactionCallbackWithoutResult() {
            @Override
            protected void doInTransactionWithoutResult(TransactionStatus s) {
                createAndSaveEntity();
            }
        });
        // Here I can see created entity and results of the trigger execution
        // But also I see all entities, which was in the database before setUp()
        // That is very strange! Why they appear if I deleted them?
        <...>
    }
}

PS:我使用的是Spring Data Neo4j 4.0.0.RELEASE和Neo4j 2.3.1

1 个答案:

答案 0 :(得分:2)

Neo4j不支持嵌套事务。因此,如果事务事件处理程序(我假设您(正确地)称为“触发器”)丰富了事务,则它需要在beforeCommit()中执行,并且它将参与全有或全无操作。测试的最佳选择是让事务提交,断言您需要断言的内容,并在每次测试之前或之后清除数据库。

GraphAware RestTest可能有助于断言和清除,如果你真的是在远程数据库上运行。如果你使用嵌入式模式进行测试,请转到GraphUnit。)

你的问题实际上是不同的。看起来像某些东西(比如SDN Session)在测试运行之间没有被清除。要么明确地清除它,要么使用@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)注释您的测试。