Grails服务不是事务性的?

Grails服务不是事务性的?,grails,service,transactions,Grails,Service,Transactions,根据这位官员和我读过的书,服务是默认的。然而,我们正在提交记录,即使我们立即抛出RuntimeException e、 g: 并这样称呼它: class myController{ MyService myService def someMethod() { myService.someMethod() } } 在上述情况下,在调用调用该服务的控制器,然后使用mysql workbench检查该行是否通过连接到DB而创建之后,该行确实已提交,并且没有回滚

根据这位官员和我读过的书,服务是默认的。然而,我们正在提交记录,即使我们立即抛出RuntimeException

e、 g:

并这样称呼它:

class myController{
   MyService myService
    def someMethod() {
         myService.someMethod()
    }
}
在上述情况下,在调用调用该服务的控制器,然后使用mysql workbench检查该行是否通过连接到DB而创建之后,该行确实已提交,并且没有回滚

所以我们下一步尝试了这个:

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

接下来,我们尝试了以下方法:

class MyService {
    static transactional = true
    def someMethod() {
        new someDomainObject().save(failOnError:true)
        throw new RuntimeException("rollback!")
    }
}
@Transactional
class MyService {
    static transactional = true
    def someMethod() {
        new SomeDomainObject().save(failOnError:true)
        throw new 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与static transasnational=true不同吗


这些服务类是Intellij14从Grails视图的Services文件夹中使用“newGroovy类”选项生成的。“new Grails Service”选项对我们不起作用,它什么也不做,所以我们必须“手动”在正确的位置创建所有groovy类。

这没有多大意义。服务的所有不同变体都应具有相同的功能。使用的一般逻辑是在类级别或至少在一个方法上查找
@Transactional
。如果使用
org.springframework.transaction.annotation.Transactional
,则将创建事务代理。如果您使用较新的
grails.transaction.Transactional
,则AST将重写方法以使用事务模板,但净效果基本相同。如果没有注释,那么除非您有
static transactional=false
,否则服务是事务性的,并且创建了一个Spring代理(与您在类级别包含Spring
@transactional
注释的情况相同)
static transactional=true
是默认设置,因此不需要它;服务完全非事务性的唯一方法是包含
static transactional=false
,并且没有
@transactional
注释

可能发生的一件事是,底层表可能不是事务性的。较新版本的MySQL默认使用InnoDB作为表类型,但在5.5之前,默认使用MyISAM。Grails会自动检测数据库并为您注册Hibernate方言,这在大多数情况下都能很好地工作,MySQL+MyISAM除外。为确保始终使用InnoDB,请在DataSource.groovy中指定适当的方言,例如

dataSource {
   dialect = org.hibernate.dialect.MySQL5InnoDBDialect
}

这只对Hibernate创建的新表有帮助。确保将任何现有的MyISAM表转换为InnoDB(尽管在这种情况下,由于您使用的是create drop,因此不需要这样做)。

确定,找到原因,或者:

“使用事务性注释服务方法将禁用该服务的默认Grails事务性行为”

因此,我碰巧将服务中的许多方法中的一个注释为
@Transactional(propagation=propagation.REQUIRES_NEW)
,认为其他方法将保留其默认的事务性,但不,如果您做出任何声明,它会默默地删除所有其他方法的事务性行为,即使您说“
static transactional=true


这似乎相当危险,从现在开始,我将用
@Transactional
注释每个服务类,以避免被发现。

这里没有足够的信息。这些服务是如何使用的,您是创建自己的实例还是创建一个实例变量,Grails可以将Spring托管bean注入其中?可以吗您在一个针对H2运行的小示例中重现了这一点(为了排除mysql实例设置中可能出现的问题)?