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

问题描述 投票:0回答:5

背景简介:我们刚刚开始使用 Hibernate 将 ERP 系统迁移/重新实现到 Java,目标是使用该系统的并发用户数为 50-100 个。我们使用 MS SQL Server 作为数据库服务器,这足以满足负载。

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

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

提醒一下,四种事务隔离级别:

  • 阅读未提交的内容
  • 已提交阅读
  • 可重复阅读
  • 可序列化
sql database database-design transactions
5个回答
18
投票

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

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

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


2
投票

不要忘记 SNAPSHOT,它位于 SERIALIZABLE 的正下方。

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


2
投票

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

您可以提出这样的论点:如果您在设计系统时考虑到这一点,则可以使用 READ_UNCOMMITTED 作为默认值,并且仅在需要时才增加隔离级别。无论如何,绝大多数事务都会成功,因此读取未提交的数据并不是什么大问题。

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


1
投票

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


0
投票

Read Uncommissed 绝对是大多数论坛中的弱势群体。然而,使用它的理由超出了经常指出的“速度与准确性”的问题。

假设您有:

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

读提交后,上述事务只有提交后才会释放。那么你可能会遇到这样的情况:T1 正在等待 T2 释放 A,T2 正在等待 T1 释放 B。这里两个事务在锁中发生冲突。

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

替代方法是使用未提交的读取。然后,您设计事务时假设可能存在脏读。我个人认为这个问题比连锁火车残骸更局部化和更容易治疗。

脏读带来的问题可以通过

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

  • (2)使用应用锁创建运行的锁定机制 在更高的抽象级别,每个锁更接近于 现实世界的资源或行动。

© www.soinside.com 2019 - 2024. All rights reserved.