繁体   English   中英

什么是Grails的“交易”服务?

[英]What is a Grails “transactional” service?

我正在阅读有关服务的Grails文档,该文档大量提及了事务/事务性,但并未真正定义事务服务方法的真正含义。

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

这到底是什么意思? 事务方法是仅使用JPA / JDBC与关系数据库进行通信的事务方法,还是适用于JTA涵盖的所有事务

有什么理由为什么我不会将服务类@Transactional为万一它演变为某天使用事务? 换句话说,是否存在使所有服务方法都具有事务性的性能问题?

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

static transactional = false

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

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

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

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

您可以在我所做的有关Grails中事务的讨论中获得更多信息。

首先,如果您对性能的担心是由于您的服务具有事务性而造成的,那么您已经达到了必杀技。 我之所以这样说,是因为在这成为主要(甚至是次要)问题之前很久,您的应用程序中就会出现许多其他瓶颈。 所以,不要为此烦恼。

通常在Grails中, transaction与数据库连接或休眠会话的事务状态有关。 尽管可以由JTA通过适当的Spring配置来管理。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM