简短背景:我们刚刚开始使用Hibernate将ERP系统迁移/重新实现到Java,目标是使用该系统的50-100个用户的并发用户数。我们使用MS SQL Server作为数据库服务器,这对于这种负载来说已经足够了。
现在,旧系统根本不使用任何事务,并依赖于设置手动锁(使用标志)和释放它们的关键部分(例如库存变化)。这就像手动交易管理。但有时数据不一致存在问题。在新系统中,我们希望使用事务来消除这些问题。
现在的问题是:如果使用大约85%的OLTP和15%的OLAP,那么用于ERP系统的良好/合理的默认事务隔离级别是什么?或者我应该总是根据每个任务决定使用哪个事务级别?
并提醒四个事务隔离级别:READ UNCOMMITTED,READ COMMITTED,REPEATABLE READ,SERIALIZABLE
答案 0 :(得分:16)
100次中的99次,读取提交是正确的答案。这可确保您只看到其他会话已提交的更改(因此,假设您已正确设计事务,结果是一致的)。但它并没有强制执行可重复读取或可序列化的锁定开销(特别是在非Oracle数据库中)。
偶尔,您可能希望运行一个报告,您愿意牺牲速度的准确性并设置读取未提交的隔离级别。这很少是一个好主意,但有时可以采用合理的方法来解决争用问题。
当您的流程需要在整个运行期间查看一致的数据集时,有时会使用可序列化和可重复读取,而不管当时其他事务正在执行什么操作。将月末协调过程设置为可序列化可能是适当的,例如,如果存在大量过程代码,用户将在过程运行时进行更改的可能性以及过程需要的要求确保始终查看对帐开始时存在的数据。
答案 1 :(得分:2)
不要忘记SNAPSHOT,它位于SERIALIZABLE之下。
这取决于数据在报告中的准确程度。这确实是一项任务。
答案 2 :(得分:2)
这在很大程度上取决于您如何设计应用程序,简单的答案就是在READ_COMMITTED上运行。
如果您在设计系统时考虑到可以使用READ_UNCOMMITTED作为默认值,并且只在需要时增加隔离级别,则可以提出一个论点。绝大多数交易都会成功,因此阅读未提交的数据并不是什么大问题。
隔离级别影响查询的方式取决于您的目标数据库。例如,Sybase和MSSQL等数据库在运行READ_COMMITTED时必须锁定比Oracle等数据库更多的资源。
答案 3 :(得分:1)
对于SQL Server(可能是大多数主要的RDBMS),我坚持使用默认值。对于SQL Server,这是READ COMMITTED。还有更多的事情,你开始过度使用数据库,没有任何东西,你就会遇到一致性问题。
答案 4 :(得分:0)
Read Uncommitted绝对是大多数论坛的弱者。但是,有理由使用它超出了经常指出的“速度与准确度”的问题。
假设你有:
使用read committed,上面的事务在提交之前不会释放。然后你可以遇到T1等待T2释放A的情况,T2正在等待T1释放B.这里两个事务发生冲突。
您可以重写这些程序以避免这种情况(例如:始终按字母顺序获取资源!)。但是,由于有太多并发用户和数万行代码,这个问题很可能变得很难诊断和解决。
另一种方法是使用Read Uncommitted。然后,假设可能存在脏读,则设计事务。我个人认为这个问题比互锁的火车残骸更加本地化和可治疗。
脏读的问题可以被
抢占(1)回滚:不要。如果出现硬件故障,网络故障或程序崩溃,这应该是最后一道防线。
(2)使用应用程序锁创建一个可以运行的锁定机制 在更高的抽象层次,每个锁更接近a 现实世界的资源或行动。