2017-02-16 35 views
1

回滚都是在这里完成的预期:Grails的(2.3)@事务不会回退

@Transactional(propagation = Propagation.REQUIRES_NEW) 
def test1() { 
    def dummy = new Dummy(name: "test1") 
    dummy.save() 
    throw new RuntimeException("test1!") 
} 

但在这里没有 - 这可能是错误的 - try/catch语句应该不会影响到行为:

@Transactional(propagation = Propagation.REQUIRES_NEW) 
def test2() { 
    def dummy = new Dummy(name: "test2") 
    dummy.save() 
    try { 
    throw new RuntimeException("test2!") 
    } catch (all) { 
    println all.message 
    } 
} 

回答

1

也许你误会尝试捕捉的目的,或者你只是有一个不稳定的时刻:

@Transactional(propagation = Propagation.REQUIRES_NEW) 
def test2() { 
    //you may be doing other stuff here 
    //but now about to do some transaction work 
    //so lets wrap this method around a try catch 
    try { 
    //this is happening 
    def dummy = new Dummy(name: "test2") 
    dummy.save()  
    } catch (Exception all) { // or catch (Throwable all) { 
    // if something went wrong in above save method 
    //should be caught and runtime exception means roll back 
    throw new RuntimeException("test2!" +all?.toString()) 
    } 
} 

我希望它解释你出错的地方,但是你真的希望在服务中做所有这些事情,并且在控制器中做试试抓住的部分 -

所以你做事务工作,如果事情出错了,你可能希望抛出额外的例外控制器中的try catch会捕获并将其设置回滚的服务。

I did a sample project years back here希望它有助于

eitherway那些都是别人的实验,是不是真的,你会去这样做正确的编码方式,我的意思是做事情的一个相当奇怪的不寻常的方式,并在很短,他只是试图使其抛出运行时异常,从而触发回滚。我坚持我的建议,答案是你想在控制器中试一试。它试图捕获手头对象的验证错误以及任何特定服务交易工作失败的失败。 Something like this但是可能还有很多工作要捕获所有特定问题并返回到带有潜在问题的原始页面 - 现在也回滚事务。

+0

我一直盼望代理反正承认例外。见测试2浏览:http://devhobbs.blogspot.de/2015/04/grailsgorm-transactions.html(测试2的结果:没有书面记录异常回滚。) –

+0

只是要清楚,你是在一个服务? '@Transactional(传播= Propagation.REQUIRES_NEW) DEF TEST1(){'是在服务?而不是控制器,因为如果你看看你提供的例子'@Transactionalclass BookService {' – Vahid

+0

我更新了我的回答,因为我的评论回来了关于你的例子等会太长检查更新的答案 – Vahid

2

默认情况下,@Transactional包装该方法,以便任何未检查的异常(即,RuntimeException)都将导致事务回滚。

如果赶上/处理方法中的例外,当然,异常不会传播到事务包装和交易将不被标记为只回滚。这似乎是你在做什么。

值得指出的是,你可以指示事务包装应该回滚事务,如果其他抛出异常(并传播到包装)。您可以使用rollbackFor注释参数执行此操作。

例如,

@Transactional(rollbackFor=Throwable.class) 
void doTransactionalWork() throws MyException { ... } 

会导致事务被回滚,如果任何的Throwable向上传播到包装纸,甚至那些被检查(即,MyException

这应该是无论您是创建新事务还是继承现有事务上下文,都可以使用任何@Transactional方法的行为。