当commit()在Spring程序化事务中抛出异常时,是否需要调用rollback()方法?

时间:2014-12-06 14:25:51

标签: java spring transactions rollback

我有一个jUnit测试,我测试我的实体 - 音乐家是否必须具有唯一名称,我正在检查数据库是否按预期拒绝了。我决定手动管理Spring中的事务,以便更好地了解正在发生的事情,而不是使用@Transactional方法。我在PlatformTransactionManager的rollback()方法的文档中读到,当commit()抛出错误时,我不能对txManager执行rollback(),因为commit()已经回滚了这个事务。它上面的链接是here。但是当我不调用这个rollback()方法时,DB进入非法状态,整个模式被破坏并且测试停止。当我添加一个IF以确保tx未完成并且一次调用rollback()方法时,一切正常。这是代码:

@Test
public void testAddMusicianWithNotUniqueName() throws Exception {
    System.out.println("addMusicianWithNotUniqueName");
    Musician musician1 = new Musician();
    musician1.setName("Musician 1");
    Musician musician2 = new Musician();
    musician2.setName("Musician 1");

    TransactionStatus status = null;
    try {
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        status = txManager.getTransaction(def);
        musicianDao.addMusician(musician1);
        musicianDao.addMusician(musician2);
        txManager.commit(status);
        fail("MusicianException was not thrown when musician's name was not unique");
    } catch (DataAccessException ex) {
        //now I added this code, even if
        //commit thrown error so it has already cleaned the transaction as said in documentation
        if(!status.isCompleted()){
            //but it apparently didn't clean the transaction as it is still not completed
            txManager.rollback(status);
        }
    }
}

你能解释一下吗?提前谢谢。

1 个答案:

答案 0 :(得分:0)

您尚未添加完整代码。但是,原因是您首先提交事务,然后失败JUnit测试。交易将根据您的代码提交。如果您不想提交数据,请尝试以下操作:

fail("MusicianException was not thrown when musician's name was not unique");
txManager.commit(status);

这将抛出java.lang.AssertionError,因此不会提交事务。