为什么以下代码使用org.springframework.dao.DuplicateKeyException失败

时间:2017-04-19 09:30:26

标签: hibernate grails gorm

//following code is executed from non-transactional service
Member member = Member.get(1)
try{
    Member.withNewTransaction {
        throw new RuntimeException("error")
    }
}catch(Exception e) {
    //handle exception
}
member.username = "Fred"
member.save()

以下代码在最后一行

时失败
org.springframework.dao.DuplicateKeyException: a different object with the same identifier value was already associated with the session: [com.test.Member#1]; nested exception is org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [com.test.Member#1]

我不希望这段代码失败,因为异常导致TX回滚,但是它被捕获,所以流程传递给下一个语句。实际情况是,从发生异常和回滚的角度来看,任何后续保存都会失败并显示DuplicateKeyException

我认为这必须对hibernate会话做一些事情,当回滚发生时会被破坏,并且hibernate不再持有任何附加到此会话的内容(错误会产生误导)。

任何人都可以请更详细地解释实际发生的事情以及处理此案例的最佳做法是什么?

到目前为止,我找到了3个解决方案:

解决方案#1 - 将交易置于其自己的会话

Member.withNewSession {
    Member.withNewTransaction {
        throw new RuntimeException("error")
    }
}

解决方案#2 - 在回滚发生后重新选择成员

member = Member.get(member.id)
member.username = "Fred"
member.save()

解决方案#3 - 启动主交易

Member.withTransaction {
    Member member = Member.get(1)
    try {
        Member.withNewTransaction {
            throw new RuntimeException("error")
        }
    } catch(Exception e) {
        //handle exception
    }
    member.username = "Fred"
    member.save()
}

0 个答案:

没有答案