【问题标题】:What is the relationship between blocking, locking, and isolation levels?阻塞、锁定和隔离级别之间的关系是什么?
【发布时间】:2010-08-06 17:49:31
【问题描述】:

我对 Oracle 阻塞有点了解——更新如何阻塞其他更新直到事务完成,编写器如何不阻塞读取器等。

我了解悲观和乐观锁定的概念,以及有关丢失丢失更新等的典型银行教科书示例。

我也了解 JDBC 事务隔离级别,例如,我们很高兴看到未提交的数据。

不过,我对这些概念之间的关联和交互方式有些模糊。例如:

  • Oracle 是否提供悲观或 默认情况下乐观锁定(它 似乎只是阻止了单独的 更新基于两个实验 TOAD 会议。)
  • 如果我怀疑这些是 应用程序级别的概念,为什么要 我不厌其烦地实施 锁定策略时我可以让 数据库同步事务 还是更新?
  • 当我的应用程序以外的其他客户端以不同的隔离级别访问时,事务隔离级别(我在连接上设置)如何改变数据库行为。

非常感谢任何澄清这些主题的文字!

【问题讨论】:

标签: java database oracle transactions isolation


【解决方案1】:
  • Oracle 允许使用任一类型的锁定 - 您构建应用程序的方式决定了所使用的内容。回想起来,这并不是一个真正的数据库决定。

  • 大多数情况下,Oracle 的锁定在与数据库的有状态连接中就足够了。在无状态应用程序中,例如 Web 应用程序,您不能使用它。在这种情况下,您必须使用应用程序级锁定,因为锁定适用于会话。

  • 通常您无需担心。在 Oracle 中,读取器从不阻塞写入器,写入器从不阻塞读取器。 Oracle 的行为不会随着各种 ANSI 隔离级别而改变。例如,Oracle 中没有“脏读”之类的东西。 Tom Kyte 指出,允许脏读的精神是避免阻塞读,这在 Oracle 中不是问题。

我强烈建议您阅读 Tom Kyte 的优秀著作“专家级 Oracle 数据库架构”,其中非常清楚地解决了这些和其他主题。

【讨论】:

  • Oracle 确实有一些不同的隔离级别和不同的行为。例如,serilizable 可能会在提交时导致“无法序列化事务”错误,这在正常的隔离级别中是看不到的。
  • 这是我知道的唯一例外,并且不常用。如果你需要使用它,那么你需要意识到这一点。 Oracle 的多版本实现负责其他 ANSI 隔离级别。
【解决方案2】:

乐观锁定基本上是“我只会在修改数据时锁定数据,而不是在读取数据时锁定”。问题是,如果您不立即锁定数据,其他人可以在您这样做之前更改它并且您正在查看旧新闻(并且可以盲目地覆盖在您读取数据和更新数据之间发生的更改。 )

悲观锁定是在您读取数据时锁定数据,以便在您决定更新数据时确保没有人更改它。

这是一个应用程序决策,而不是 Oracle 决策:

从表 1 中选择 x、y、z,其中 a = 2

不会锁定匹配的记录但是

SELECT x, y, z FROM table1 WHERE a = 2 FOR UPDATE

会的。所以你必须决定你是否接受乐观锁定

SELECT x, y, z FROM table1 WHERE a = 2

...时间流逝...

UPDATE table1
   SET x = 1, y = 2, z = 3
 WHERE a = 2

(您可能已经覆盖了其他人在此期间所做的更改)

还是需要悲观:

SELECT x, y, z FROM table1 WHERE a = 2 FOR UPDATE

...时间流逝...

UPDATE table1
   SET x = 1, y = 2, z = 3
 WHERE a = 2

(您确定自从您查询数据以来没有人更改过数据。)

在此处查看 Oracle 中可用的隔离级别。 http://download.oracle.com/docs/cd/B19306_01/server.102/b14220/consist.htm#CNCPT621

【讨论】:

    【解决方案3】:

    Oracle 总是处理悲观锁定。也就是说,它会在更新时锁定记录(如果涉及到密钥,您也可以锁定删除和插入)。您可以使用 SELECT....FOR UPDATE 来增强悲观锁定策略。

    实际上,任何以事务方式工作的数据库/存储引擎都必须进行某种形式的锁定。

    SERIALIZABLE 隔离级别更接近于乐观锁定机制。如果事务尝试更新自事务开始以来已更新的记录,它将引发异常。但是,它依赖于数据库会话和最终用户会话之间的一对一关系。

    随着连接池/无状态应用程序变得普遍,尤其是在用户活动繁重的系统中,长时间绑定数据库会话可能是一个糟糕的策略。乐观锁定是首选,更高版本的 Oracle 通过 ORA_ROWSCN 和 ROWDEPENDENCIES 项支持此功能。基本上,它们可以更轻松地查看自您最初/上次查看记录以来是否已更改记录。

    由于数据库会话和用户会话之间的一对一关系已经成为传统,应用程序层保留了更多的“用户会话”状态,因此更加负责检查用户所做的选择5/10 分钟前仍然有效(例如,这本书还在存货中,还是其他人购买了它)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-27
      • 2013-04-16
      • 1970-01-01
      • 2019-04-22
      • 2014-09-18
      • 2013-12-09
      相关资源
      最近更新 更多