代码之家  ›  专栏  ›  技术社区  ›  MicSim

ERP的最佳默认事务隔离级别是什么(如果有的话)?

  •  14
  • MicSim  · 技术社区  · 16 年前

    简短背景:我们刚刚开始使用Hibernate将ERP系统迁移/重新实现到Java,目标是使用该系统的并发用户数为50-100。我们使用MS SQL Server作为数据库服务器,这对于这种负载来说已经足够好了。

    现在,旧系统根本不使用任何事务,关键部分(如库存变更)依赖于设置手动锁(使用标志)并释放它们。这类似于手动事务管理。但有时会出现数据不一致的问题。在新系统中,我们希望使用事务来消除这些问题。

    现在的问题是:什么是好的/合理的 不履行 考虑到约85%的OLTP和15%的OLAP的使用率,ERP系统使用的事务隔离级别?或者,我是否应该始终根据每个任务来决定使用哪个事务级别?

    作为提醒,有四个事务隔离级别:READ UNCOMMITED、READ COMMITTED、REPEATABLE READ、SERIALIZABLE

    5 回复  |  直到 15 年前
        1
  •  18
  •   Justin Cave    16 年前

    100次中有99次,阅读承诺是正确的答案。这确保您只看到其他会话提交的更改(因此,假设您正确设计了事务,结果是一致的)。但它不会像可重复读取或可序列化那样施加锁定开销(特别是在非Oracle数据库中)。

    偶尔,您可能希望运行一个报告,在该报告中,您愿意为了速度而牺牲准确性,并设置一个读取未提交的隔离级别。这很少是一个好主意,但它偶尔是锁定争用问题的一个合理可接受的解决方法。

    当您的进程需要在整个运行过程中看到一组一致的数据时,偶尔会使用可序列化和可重复的读取,而不管当时其他事务在做什么。将月末对账流程设置为可序列化可能是合适的,例如,如果有很多程序代码,用户可能会在流程运行时进行更改,并且流程需要确保始终看到对账开始时存在的数据。

        2
  •  2
  •   Robert C. Barth    16 年前

    别忘了SNAPSHOT,它就在SERIALIZABLE下面。

    这取决于报告中数据的准确性有多重要。这真的是一个任务一个任务的事情。

        3
  •  2
  •   BeWarned    16 年前

    这在很大程度上取决于你如何设计你的应用程序,简单的答案就是在READ_COMMITTED上运行。

    你可以说,如果你在设计系统时考虑到这一点,你可以使用READ_UNCOMMITTED作为默认值,只在需要时增加隔离级别。无论如何,你的绝大多数事务都会成功,所以读取未提交的数据不会有什么大不了的。

    隔离级别影响查询的方式取决于目标数据库。例如,运行READ_COMMITTED时,Sybase和MSSQL等数据库必须锁定比Oracle等数据库更多的资源。

        4
  •  1
  •   chadmyers    16 年前

    对于SQL Server(可能是最主要的RDBMS),我会坚持使用默认值。对于SQL Server,这是READ COMMITTED。再多一点,你就开始给数据库带来过重的负担,再少一点,你就会遇到一致性问题。

        5
  •  0
  •   cat_in_hat    7 年前

    在大多数论坛中,未承诺阅读绝对是弱者。然而,使用它的原因不仅仅是人们经常指出的“速度与精度”问题。

    假设你有:

    • 事务T1:写入B,读取A(更多工作),提交。
    • 事务T2:写入A,读取B(更多工作),提交。

    通过read committed,上述事务在提交之前不会释放。然后,您可能会遇到T1正在等待T2释放a,T2正在等待T1释放B的情况。在这里,两个事务在锁中碰撞。

    您可以重写这些过程以避免这种情况(例如:始终按字母顺序获取资源!)。尽管如此,由于并发用户太多,代码行数数万行,这个问题很可能变得很难诊断和解决。

    另一种方法是使用Read Uncommitted。然后,您在设计交易时假设可能存在脏读。我个人认为这个问题比联锁的火车失事更具局限性和可治疗性。

    脏读产生的问题可以通过以下方式抢占

    • (1) 回滚:不要。这应该是硬件故障、网络故障或程序崩溃时的最后一道防线。

    • (2) 使用应用程序锁创建可操作的锁定机制 在更高的抽象层次上,每个锁都更接近 现实世界的资源或行动。