Grails服务不是事务性的? [英] Grails services are not transactional?

查看:294
本文介绍了Grails服务不是事务性的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据官方的文档和我已阅读的书籍,服务是跨国违约。然而,即使我们立即抛出一个RuntimeException,我们也得到了提交的记录。



例如:

  class MyService {
def someMethod (){
new someDomainObject()。save(failOnError:true)
抛出新的RuntimeException(rollback!)
}
}

然后调用它:

  class myController {
MyService myService
def someMethod(){
myService.someMethod()
}
}


因此,我们接下来尝试了这一点:

  class MyService {
static transactional = true
someMethod(){
new someDomainObject()。save(failOnError:true)
抛出新的RuntimeException(rollback!)


Sam

接下来我们尝试了这一点:

  @Transactional 
class MyService {
static transactional = true
def someMethod(){
New SomeDomainObject()。save(failOnError:true)
抛出新的RuntimeException(rollback! )
}
}

最后,这是有效的。然而,我们不明白为什么。

注意:
使用MYSQL的Grails 2.4.4:

  development {
dataSource {
dbCreate =create-drop
url =jdbc:mysql://127.0.0.1:3306 / db
username =user
password =***
}
}

这是正常行为吗?

@Transactional不同于静态tranasctional = true吗?



生成了Service类由intellij 14使用Grails视图中Services文件夹中的new groovy class选项。 新的Grails服务选项对我们来说不起作用,它什么都不做,所以我们必须在正确的地方手工创建所有常规类。

解决方案

好的,找到原因,或者找不到:

使用Transactional注释服务方法会禁用该服务的默认Grails事务行为



所以我碰巧在服务中注释了许多方法之一: @Transactional(propagation = Propagation.REQUIRES_NEW),认为其他人将保留它们的默认事务性,但是不,如果你做出任何声明,即使你说 static transactional = true



这似乎相当危险,从现在开始,我将使用 @Transactional 以避免被发现。


According to the official documentation, and the books I have read, services are transnational be default. however, we were getting records committed, even if we immediately throw a RuntimeException.

e.g:

class MyService {
    def someMethod() {
        new someDomainObject().save(failOnError:true)
        throw new RuntimeException("rollback!")
    }
}

and calling it thusly:

class myController{
   MyService myService
    def someMethod() {
         myService.someMethod()
    }
}

In the above case, after calling the controller which calls the service, then checking if the row was created by attaching to the DB using mysql workbench, the row was indeed committed and not rolled back.

So we next tried this:

class MyService {
    static transactional = true
    def someMethod() {
        new someDomainObject().save(failOnError:true)
        throw new RuntimeException("rollback!")
    }
}

Same problem.

Next we tried this:

@Transactional
class MyService {
    static transactional = true
    def someMethod() {
        new SomeDomainObject().save(failOnError:true)
        throw new RuntimeException("rollback!")
    }
}

Finally, this works. However, we dont understand why.

Note: Grails 2.4.4 using MYSQL:

development {
    dataSource {
        dbCreate = "create-drop"
        url = "jdbc:mysql://127.0.0.1:3306/db"
        username = "user"
        password = "***"
    }
}

Is this normal behavior?
Is @Transactional different to static tranasctional=true?

The Service classes were generated by intellij 14 using the "new groovy class" option from the Services folder in the Grails view. The "new Grails Service" option does not work for us, it just does nothing, so we have to create all groovy classes "by hand" in the right place.

解决方案

OK, found the cause, or Gotcha:

"Annotating a service method with Transactional disables the default Grails transactional behavior for that service"

So I happened to annotate one of the many methods in the service as @Transactional(propagation=Propagation.REQUIRES_NEW), thinking that the others will retain their default of transactional, but no, if you make any declarations, it removes the transactoinal behavior of all other methods silently, even if you say "static transactional = true"

This appears to be rather dangerous, and from now on, I will annotate every service class with @Transactional to avoid being caught out.

这篇关于Grails服务不是事务性的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆