【问题标题】:How expensive are transactions in Grails?Grails 中的交易有多昂贵?
【发布时间】:2014-12-09 23:44:08
【问题描述】:

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

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

有没有关于交易成本的数据的地方? [时间和资源方面]

【问题讨论】:

  • 使用 Visual VM 之类的工具来分析您的应用程序并执行 A/B。涉及的因素太多,不能说它是 X 或 Y 更贵/更便宜。这取决于您的应用程序。测量它。
  • 我们发现在我们的应用程序中交易的成本高得惊人。我们现在将我们的服务分为“事务性”和“非事务性”版本——通过这样做,我们设法获得了很多快速的性能提升,特别是对于在循环中调用的服务方法。正如@JoshuaMoore 建议的那样,使用分析器来查看应用程序中事务的影响。

标签: performance grails groovy transactions


【解决方案1】:

如果有人告诉您,从您的服务中删除交易是提高性能的好方法,那么您不应该听从该人的任何未来建议。您应该查看在事务中花费的时间并确定真正的开销是多少,并找到在事务中运行但不需要的方法和整个服务,并将它们修复为非事务性的。但是删除所有交易是不负责任的。

您会故意在方法返回值中添加零星错误并使您的数据不一致,当您有大量流量时,情况会变得更糟。速度稍快但有问题的应用程序或网站不会流行,如果这对性能没有帮助(或没有太大帮助),那么您仍然需要做真正的工作来查找瓶颈、丢失的索引和其他事情确实会造成问题。

我会从所有控制器中删除所有@Transactional 注释和数据库写入;不是出于性能原因,而是为了保持应用层的合理性,并且不会被不相关的代码和逻辑污染。

如果您发现一个或多个不需要事务的服务方法,请根据需要切换到对每个事务性方法进行注释,但在类范围内省略注释,因此未注释的方法不会继承任何内容并且不是事务性的。您还可以将这些方法移至非事务性服务。

请注意,只有在没有 @Transactional 注释并且有 transactional 属性禁用该功能时,服务才是非事务性的:

static transactional = false

如果你没有那个属性并且没有注解,看起来没问题,但是transactional如果没有指定默认为true。

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

【讨论】:

    猜你喜欢
    • 2011-12-06
    • 2011-04-05
    • 1970-01-01
    • 2016-01-31
    • 2010-10-08
    • 1970-01-01
    • 2012-08-27
    • 2012-01-26
    • 2011-01-06
    相关资源
    最近更新 更多