- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有以下代码:
class ServiceA {
def save(Object object) {
if (somethingBadComesBack) {
throw new CustomRuntimeException(data)
}
}
}
class ServiceB {
def serviceA
def save(Object object) {
try {
serviceA.save(object)
// do more stuff if good to go
} catch(CustomRuntimeException e) {
// populate some objects with errors based on exception
}
}
}
class ServiceC {
def serviceB
def process(Object object) {
serviceB.save(object)
if (object.hasErrors() {
// do some stuff
}else{
// do some stuff
}
def info = someMethod(object)
return info
}
}
class SomeController {
def serviceC
def process() {
def object = .....
serviceC.save(object) // UnexpectedRollbackException is thrown here
}
}
ServiceA.save()
并发生异常时,
ServiceC.save()
尝试返回时会抛出
UnexpectedRollbackException
。
try {
serviceC.process(object)
}catch(UnexpectedRollbackException e) {
println e.getMostSpecificCause()
}
org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
最佳答案
您正在使用运行时异常来回滚事务,但这是作弊-它利用了副作用。运行时异常会自动回滚事务,因为您不需要捕获它们,因此假定如果引发了异常,则不会发生,默认行为是回滚。您可以将方法配置为不为特定的预期运行时异常回滚,但这很少见。被检查的异常不会回滚异常,因为在Java中必须捕获它们或在throws
中声明它们,因此您必须显式地抛出它或将其隐藏。无论哪种方式,您都有机会再试一次。
正确回滚事务的正确方法是在当前setRollbackOnly()
上调用TransactionStatus
,但这不能在服务方法中直接访问(由于它是闭包的参数,因此在withTransaction
块中)。但是很容易做到:导入org.springframework.transaction.interceptor.TransactionAspectSupport
并调用TransactionAspectSupport.currentTransactionStatus().setRollbackOnly()
。这将需要您对代码进行重新处理,因为不会捕获任何异常,因此您需要检查它是否已使用TransactionAspectSupport.currentTransactionStatus().isRollbackOnly()
回滚。
我不确定这是Grails的问题还是标准行为,但是在进行调试时,使用3个不同的TransactionStatus
实例进行了3次commit调用。只有第一个设置了回滚标志,但是第二个知道了第一个并且还可以。第三个被认为是新事务,并且触发了您所看到的相同异常。因此,要解决此问题,我将其添加到了第二和第三服务方法中:
def status = TransactionAspectSupport.currentTransactionStatus()
if (!status.isRollbackOnly()) status.setRollbackOnly()
UnexpectedRollbackException
。
setRollbackOnly()
并抛出一个已检查的异常,那么您将能够使用与现在相同的常规工作流程。
关于exception - Grails UnexpectedRollbackException发生: Not Sure Why,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13482103/
我是一名优秀的程序员,十分优秀!