Grails 什么是圣杯;“交易性”;服务

Grails 什么是圣杯;“交易性”;服务,grails,service,transactions,jta,Grails,Service,Transactions,Jta,我正在阅读Grails文档,其中多次提到事务/事务性,但没有真正定义什么是事务性服务方法 鉴于服务的性质,它们经常需要事务性行为 这到底意味着什么?事务性方法是否只是那些使用JPA/JDBC与关系数据库通信的方法,或者它们是否适用于JTA涵盖的任何内容 有什么理由不让一个服务类@Transactional,以防它发展到某一天使用事务?换句话说,使所有服务方法都是事务性的是否存在性能问题?首先,如果您的性能问题是由于您的服务是事务性的,那么您已经达到了nirvana。我这么说是因为在这成为一个主要

我正在阅读Grails文档,其中多次提到事务/事务性,但没有真正定义什么是事务性服务方法

鉴于服务的性质,它们经常需要事务性行为

这到底意味着什么?事务性方法是否只是那些使用JPA/JDBC与关系数据库通信的方法,或者它们是否适用于JTA涵盖的任何内容


有什么理由不让一个服务类
@Transactional
,以防它发展到某一天使用事务?换句话说,使所有服务方法都是事务性的是否存在性能问题?

首先,如果您的性能问题是由于您的服务是事务性的,那么您已经达到了nirvana。我这么说是因为在这成为一个主要(甚至次要)问题之前,应用程序中还有很多其他瓶颈。所以,不要为此烦恼

通常在Grails中,事务与数据库连接或hibernate会话的事务状态相关。尽管它可以是JTA通过正确的Spring配置管理的任何东西


简单来说,它通常意味着(默认情况下)数据库事务。

Grails服务默认情况下是事务性的-如果您不希望服务是事务性的,则需要删除所有
@transactional
注释(Grails的
@Grails.transaction.Transactional
和Spring的
@org.springframework.transaction.annotation.Transactional
)和添加

如果您没有使用
transactional
属性禁用事务,并且没有注释,则服务的工作原理与使用Spring注释时的工作原理相同。也就是说,Spring在运行时创建类的CGLIB代理,并将代理的一个实例注册为Springbean,并将其委托给您的类的一个实例执行数据库访问和业务逻辑的实际类。这允许代理拦截所有公共方法调用并启动新事务、加入现有事务、创建新事务等

较新的Grails注释具有与Spring注释相同的所有设置,但其工作方式有所不同。在编译期间,每个方法都由AST转换重写,而不是触发单个代理的创建,实质上是为每个方法创建一个迷你代理(这显然是一种简化)。这更好,因为数据库访问和事务语义是相同的,但是如果您从另一个使用不同设置进行注释的方法调用一个注释方法,则会尊重不同的设置。但是对于代理,它是在委托实例内的直接调用,并且绕过代理。因为代理具有所有要创建的逻辑在创建新事务或使用其他不同设置时,这两个方法将使用第一个方法的设置

事务性方法会对性能造成小的影响,如果存在大量调用和/或大量通信量,这可能会累积。在代码运行之前,会启动事务(假设某个事务未处于活动状态),为此,必须从池(数据源)检索连接并配置为关闭自动提交,并且必须进行各种事务设置(隔离、超时、只读等)。但Grails数据源实际上是围绕“真实”数据源的智能包装器。在启动查询之前,它不会获得真实的JDBC连接,因此所有配置设置都会缓存,直到在实际连接上“重播”。如果该方法不执行任何数据库工作(要么因为它从未执行过,要么因为它在db access代码触发之前根据某种条件提前退出),则基本上没有数据库成本。但如果它执行了,则一切正常

但不要依赖此数据源代理逻辑-最好明确说明哪些服务是事务性的,哪些不是事务性的,以及每个服务中哪些方法是事务性的,哪些不是事务性的。最好的方法是根据需要注释方法,或者如果所有方法都使用相同的方法,则在类级别添加单个注释设置

您可以在我做的关于Grails中事务的文章中获得更多信息

static transactional = false