【问题标题】:When do transactions become more of a burden than a benefit?什么时候交易变得更像是一种负担而不是一种好处?
【发布时间】:2008-09-17 21:21:56
【问题描述】:

在当今时代,事务性编程是现代开发的主要内容。并发性和容错性对于应用程序的寿命至关重要,因此,事务逻辑已变得易于实现。但是,随着应用程序的增长,事务代码似乎对应用程序的可伸缩性变得越来越沉重,当您桥接分布式事务和镜像数据集时,问题开始变得非常复杂。我很好奇,在数据大小或应用程序复杂性方面,事务经常开始成为问题的根源(导致超时、死锁、关键任务代码中的性能问题等),这些问题的修复、故障排除更麻烦或解决方法,而不是设计一个本身更具容错性的数据模型,或使用其他方法来确保数据完整性。此外,哪些设计模式可以最大限度地减少这些影响或使标准事务逻辑过时或不再存在?

--

编辑:到目前为止,我们已经得到了一些质量合理的答案,但我想我会自己发布一个答案,以提出我听说过的一些事情,以激发一些额外的创造力;我得到的大部分回应都是对这个问题的悲观看法。

另一个重要的注意事项是,并非所有死锁都是由于程序编码不当造成的。有时存在依赖于不同顺序的相似资源的关键任务操作,或者是不同查询中的复杂连接,它们相互叠加;这是一个有时似乎无法避免的问题,但我一直参与重新设计工作流程,以促进不太可能导致问题的执行顺序。

【问题讨论】:

  • 这个问题很主观。此外,它非常模糊,可能过于笼统,无法得到集中的答案。你应该尝试改写它。
  • 我在问题中添加了一些额外的细节,甚至根据我正在寻找的内容给出了更多的答案,但似乎这可能已被吸入 SO 漩涡中。跨度>

标签: sql performance design-patterns transactions


【解决方案1】:

我认为没有设计模式本身可以解决这个问题。良好的数据库设计、良好的存储过程编程,尤​​其是学习如何保持交易简短,将缓解大多数问题。 但是,没有 100% 保证没有问题的方法。

不过,在我职业生涯中遇到的几乎所有情况下,死锁和减速都是通过修复存储过程来解决的:

  • 确保访问所有表以防止死锁
  • 修复索引和统计信息可以让一切变得更快(从而减少死锁的机会)
  • 有时并没有真正的交易需求,只是“看起来”像它
  • 有时可以通过在单个语句中创建多个语句存储过程来消除事务。

【讨论】:

    【解决方案2】:

    从长远来看,使用共享资源是错误的。因为通过重用现有环境,您正在创造越来越多的可能性。只需回顾一下忙碌的海狸 :) Erlang 采用的方法是生成容错且易于验证的系统的正确方法。

    但事务性内存对于广泛使用的许多应用程序来说是必不可少的。例如,如果您咨询一家拥有数百万客户的银行,就不能仅仅为了效率而复制数据。

    我认为 monad 是一个很酷的概念,可以处理改变状态的困难概念。

    【讨论】:

      【解决方案3】:

      我听说过的一种方法是制作一个版本化的仅插入模型,其中不会发生任何更新。在选择期间,版本用于仅选择最新的行。我知道这种方法的一个缺点是数据库会很快变得相当大。

      我也知道一些解决方案,例如 FogBugz,不使用强制外键,我相信这也有助于缓解其中一些问题,因为 SQL 查询计划可以在选择或更新期间锁定链接表,即使没有数据它们正在发生变化,如果它是一个高度竞争的表被锁定,它可能会增加死锁或超时的机会。

      我对这些方法了解不多,因为我从未使用过它们,所以我假设每种方法都有我不知道的优点和缺点,以及我从未听说过的其他一些技术关于。

      我也一直在研究 Carlo Pescio 的 recent post 中的一些材料,不幸的是我没有足够的时间来做这件事,但这些材料似乎很有趣。

      【讨论】:

        【解决方案4】:

        如果您在这里谈论“云计算”,答案是将每个事务本地化到它在云中发生的地方。

        整个云不需要保持一致,因为这会降低性能(如您所述)。简单地说,跟踪更改的内容和位置,并在更改通过系统传播时处理多个小事务。

        用户 A 更新记录 R 并且用户 B 在云的另一端没有看到它的情况(还)与用户 A 在当前严格事务环境中尚未进行更改时的情况相同.这可能会导致更新繁重的系统出现差异,因此系统的架构应该尽可能少地处理更新 - 将事物转移到数据聚合中,并在确切数字至关重要时提取聚合(即移动一致性要求从写入时间到关键读取时间)。

        好吧,只是我的 POV。在这种情况下,很难设想一个与应用程序无关的系统。

        【讨论】:

          【解决方案5】:

          尝试以尽可能少的指令在数据库级别进行更改。

          一般规则是尽可能少地锁定资源。在 Oracle 上使用 T-SQL、PLSQL、Java 或任何类似方式可以减少每个事务锁定共享资源的时间。事实上,数据库中的事务通过行级锁、多版本和其他类型的智能技术进行了优化。如果您可以在数据库中进行交易,则可以节省网络延迟。除了 ODBC/JDBC/OLEBD 等其他层。

          有时程序员试图获得数据库的优点(它是事务性的、并行的、分布式的),但保留数据的缓存。然后他们需要手动添加一些数据库功能。

          【讨论】:

            猜你喜欢
            • 2015-08-19
            • 1970-01-01
            • 1970-01-01
            • 2012-06-15
            • 2011-06-26
            • 2012-11-02
            • 1970-01-01
            • 2013-03-02
            • 2012-01-15
            相关资源
            最近更新 更多