【发布时间】:2015-01-28 13:52:36
【问题描述】:
我正在使用 Grails 框架。
想要在失败时将某些内容保存到数据库(在抛出 RuntimeException 之后)。假设我在一个事务服务中有这样的东西:
try {
throw new RuntimeException()
} catch(Exception ex) {
new FatalErrorDomainObject().save()
}
当前版本将失败,因为会话设置为回滚。
我尝试通过多种方式解决这个问题,到目前为止我发现的是:
.withTransaction - 无法工作,因为会将事务绑定到当前会话
.withSession - 不起作用,因为只会重用现有会话
.withNewSession - 单独不起作用,因为它会在同一个线程中创建新会话(同一个线程 = 同一个数据库连接,所以它会因 SQL 异常而失败)
到目前为止,我发现的唯一可行的解决方案是创建新线程和新的休眠会话。这真的是实现这一目标的唯一(也是正确)方法吗?
public static void syncSession(Closure job) {
// Checking environment in production code it's not very elegant but thanks to this it's transparent
// for all tests and makes them DRY.
if(Environment.current == Environment.TEST) {
job.call()
}
Thread t = new Thread({
DomainObject.withNewSession {
job.call()
}
})
t.start()
t.join()
}
用法:
try {
throw new RuntimeException()
} catch(Exception ex) {
syncSession {
new FatalErrorDomainObject().save()
}
}
【问题讨论】:
标签: hibernate session exception grails transactions