为什么以及何时应该在Spring事务隔离级别中使用READ UNCOMITTED隔离级别



这可能是一个非常普通的问题。但是,我仍然无法找到一个合适的解决方案/答案,何时以及为什么我应该使用READ UNCOMITTED隔离级别。大多数文章和spring-doc都说,最有效的方法是使用SERIALIZABLE。在这种情况下,为什么spring事务管理会提出READ UNCOMMITTED&如果COMMITTED隔离级别无效,请读取它们。

我希望至少在这里我能得到答案。

提前感谢

我首先要说的是,我确实有一个共同的信念,即很难遇到需要这种隔离级别的情况。大多数时候,您希望从"可重复读取"或"可串行化"开始。


READ UNCOMMITTED的一种可能(尽管疯狂)使用是针对运行不同数据库会话但都需要获取"松散"外键的潜在客户索引的分布式系统。假设您有两个服务,它们通过REST相互通信,并通过相互协调来管理事务性:

  1. A插入一行并调用B,传递数据库生成的预测密钥,然后等待B
  2. B使用a提供的键在另一个表中插入以检索一些数据,然后提交自己的事务,最后返回一个成功供a使用
  3. A提交自己的事务

此时,两个表中的行都已插入正确的键。然后,问题转移到步骤(3)中出现问题的极少数情况。

除其他外,我认为密钥不应该由数据库生成。。。但对于现有的系统,你不一定有决定密钥在哪里生成的自由,也没有重新实现的自由,即使你对实现的糟糕程度感到震惊。


READ COMMITTED的一种可能用途可以是为每个用户公开一个数据库会话的软件,同时希望用户能够刷新内容并查看不同事务生成的新数据。一个很好的例子是数据库管理前端(SqlServerManagementStudio、Toad、Squirrel等等)。


下面的链接更详细地解释了这些隔离级别是如何在行业中使用的。这里还复制了一段摘录,以便于参考:

http://www.dbta.com/Columns/DBA-Corner/The-Danger-of-Dirty-Reads-98511.aspx

读取数据库数据的程序可以访问许多行,因此容易出现并发问题。为了解决这个问题,大多数主要的RDBMS产品都支持读通锁,也称为"脏读"或"未提交读",以帮助克服并发问题。当使用未提交读取(UR)时,应用程序可以访问已更改但尚未提交的数据。脏读取功能通常使用隔离级别来实现,但DBMS供应商的具体命名和实现不同。

使用脏读取的程序将在不获取锁的情况下读取数据。这使得应用程序能够在操作表时读取表中包含的数据。它通常会提高数据的性能和可用性,因为在这个过程中不会调用锁定机制。

。。。

在某些特定情况下,脏读功能可能是有意义的。考虑以下情况:

  • 需要访问本质上基本上是静态的引用、代码或查找表。由于数据的非易失性,脏读取在大多数情况下与正常读取没有什么不同。在这些情况下,当代码数据被修改时,任何读取数据的应用程序都会产生最小的问题(如果有的话)
  • 必须对大量数据进行统计处理。例如,您可能希望确定某一薪酬范围内女性员工的平均年龄。未提交的读取对平均多行的影响可能很小,因为更改的单个值可能不会对结果产生很大影响
  • 脏读在数据仓库环境中是非常宝贵的。数据仓库用于在线分析处理,除了定期的数据传播和/或复制之外,访问是只读的。未提交的读取在只读环境中是完美的,因为数据通常不会更改,所以它几乎不会造成损坏
  • 在极少数情况下,当一个表或一组表仅由单个用户使用时,UR会有很大的意义。如果只有一个人可以修改和访问数据,那么锁定只会增加开销
  • 最后,如果访问的数据已经不一致,那么使用脏读访问信息几乎不会造成什么危害

脏读功能可以缓解并发问题,并在非常特定的情况下提供更快的性能。在投入生产应用程序中实施UR隔离级别之前,一定要了解它的含义及其可能导致的"问题"。


最新更新