Grails中的交易有多昂贵? [英] How expensive are transactions in Grails?

查看:136
本文介绍了Grails中的交易有多昂贵?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究Grails应用程序的性能问题,建议将这些事务从服务中移除。



有没有一种方法可以衡量服务中的变化?

有没有一个有关交易费用高昂的数据的地方?如果有人告诉你,从你的服务中删除交易是一个很好的帮助你的表现的方法,你不应该听从那个人的未来建议。您应该看看在事务中花费的时间,并确定实际的开销是多少,并找到在事务中运行的方法和整个服务,但不需要将这些方法修复为非事务性。但删除所有交易将是不负责任的。

您会故意在方法返回值中添加零星错误并使数据不一致,并且当您有很多的交通。一个稍微快一点但有问题的应用程序或网站是不会流行的,如果这不利于性能(或者不是很多),那么你仍然必须做真正的工作来找到瓶颈,缺少索引和其他事情我真的会删除所有控制器中的所有 @Transactional 注释和数据库写入。不是出于性能的原因,而是为了保持应用程序层合理,并且不会受到无关的代码和逻辑的污染。



如果您发现一个或多个不需要事务的服务方法,根据需要切换到注释每个事务方法,但省略类范围的注释,所以未注释的方法不会继承任何东西,也不是事务性的。您也可以将这些方法移动到非事务性服务。



请注意,如果没有 @Transactional 注释,并有一个禁用该功能的事务性属性:

  static transactional = false 

如果您没有该属性并且没有注释,它会看起来没问题,但 transactional 如果未指定,则默认为true。



还有一些可以帮助很多(并且已经)。 dataSource bean实际上是一个代理的代理 - 一个代理从一个开放的Hibernate会话或事务使用的池中返回连接,以便您可以看到未提交的数据和在相同的连接中进行查询和更新。另一个与你的问题有更多的关系: org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy 它已经在Spring中使用了很多年,但是从2.3开始只在Grails中使用。它有助于启动或参与交易但不执行数据库工作的方法。对于不必要地启动并提交'空'事务的单个方法调用,涉及的开销包括获取池连接,然后调用 set autocommit false ,设置事务隔离水平等等。所有这些都是小的成本,但它们加起来。该类通过为您提供缓存这些方法调用的代理连接而工作,并且只在实际运行查询时才获得真正的连接并在其上调用这些方法。如果没有查询,并且唯一的调用是那些与交易相关的设置方法,那么根本没有任何成本。你不应该依赖这个,并应该有意使用@Transactional注解,但是如果你错过了这个池代理将有助于避免不必要的工作。


I'm looking at performance issues with a Grails application, and the suggestion is to remove the transactions from the services.

Is there a way that I can measure the change in the service?

Is there a place that has data on how expensive transactions are? [Time and resource-wise]

解决方案

If someone told you that removing transactions from your services was a good way to help performance, you should not listen to any future advice from that person. You should look at the time spent in transactions and determine what the real overhead is, and find methods and entire services that are run in transactions but don't need to be and fix those to be nontransactional. But removing all transactions would be irresponsible.

You would be intentionally adding sporadic errors in method return values and making your data inconsistent, and this will get worse when you have a lot of traffic. A somewhat faster but buggy app or web site is not going to be popular, and if this doesn't help performance (or not much) then you still have to do the real work of finding the bottlenecks, missing indexes, and other things that are genuinely causing problems.

I would remove all @Transactional annotations and database writes from all controllers though; not for performance reasons, but to keep the application tiers sensible and not polluted with unrelated code and logic.

If you find one or more service methods that don't require transactions, switch to annotating each transactional method as needed but omit the annotation at class scope so un-annotated methods inherit nothing and aren't transactional. You could also move those methods to non-transactional services.

Note that services are only non-transactional if there are no @Transactional annotations and there is a transactional property disabling the feature:

static transactional = false

If you don't have that property and have no annotations, it will look like it's ok, but transactional defaults to true if not specified.

There's also something else that can help a lot (and already does). The dataSource bean is actually a proxy of a proxy - one proxy returns the connection from the pool that's a being used by an open Hibernate session or transaction so you can see uncommitted data and do your queries and updates in the same connection. The other is more related to your question: org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy which has been in Spring for years but only used in Grails since 2.3. It helps with methods that start or participate in a transaction but do no database work. For the case of a single method call that unnecessarily starts and commits an 'empty' transaction, the overhead involved includes getting the pooled connection, then calling set autocommit false, setting the transaction isolation level, etc. All of these are small costs but they add up. The class works by giving you a proxied connection that caches these method calls, and only gets a real connection and invokes these method on it when a query is actually run. If there are no queries and the only calls are those transaction-related setup methods, there's basically no cost at all. You shouldn't rely on this and should be intentional with the use of @Transactional annotations, but if you miss one this pool proxy will help avoid unnecessary work.

这篇关于Grails中的交易有多昂贵?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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