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