25

我正在编写一个 Web 应用程序,其中两个不同的用户可以更新一个事情列表,例如待办事项列表。我已经意识到,乐观锁定机制效果最好,因为我不期望高争用。

我正在查看事务隔离级别,现在我有点困惑。看起来不同的事务隔离级别也解决了类似的问题。

这两个不同的概念如何相互关联?如果可能的话,举一个简单的例子。

4

2 回答 2

23

这两件事都与数据一致性和并发访问有关,但它们是两种不同的机制。

锁定可防止对某些对象的并发访问。例如,当您尝试更新待办事项列表项时,使用悲观锁定数据库会在记录上放置行锁,直到您提交或回滚事务,这样就不允许其他事务更新同一记录。乐观锁定是应用程序端检查记录的时间戳/版本在获取和尝试更新之间是否发生了变化。这与事务隔离级别无关。

事务隔离是关于读一致性

  • 读取未提交级别允许会话查看其他会话的未提交更改
  • 读取提交级别允许会话仅查看其他会话的已提交更改
  • 可序列化级别允许会话仅查看在事务开始之前提交的更改

看看下面的例子,我指出了事务隔离级别之间不同的查询结果。

SESSION 1                                  SESSION 2
--------------------------------           --------------------------------------
SELECT count(*) FROM test;
=> 10
                                           INSERT INTO test VALUES ('x');

SELECT count(*) FROM test;
=> 10 with read committed/serializable
=> 11 with read uncommited (dirty read)
                                           COMMIT;

SELECT count(*) FROM test;
=> 10 with serializable
=> 11 with read uncommitted/read committed

有四种 ANSI 指定的事务隔离级别(上例中没有提到的一个是“可重复读取”),除了可序列化之外,所有这些都受到一些异常的影响。请注意,它与锁定无关。

您可以在此处查看有关此的 Oracle 文档,这些概念非常普遍。

最后,您使用乐观锁定的方法对于 Web 应用程序似乎是明智的。很可能您获取一个列表项并在两个不同的 HTTP 请求中更新它。在获取之后通过显式锁定记录来保持事务打开是不可能的(或者至少是不明智的)(你怎么知道第二个请求是否会到达?)乐观锁定可以优雅地处理这个问题。

于 2014-03-26T22:26:43.283 回答
0

锁定机制通常用于实现事务隔离级别。因此,事务隔离级别定义了您的事务在并发执行中的行为方式。锁定机制是实现细节。

从应用程序编写的角度来看,您应该专注于设置适当的事务隔离级别。当然,设置特定的隔离级别意味着锁定,但只要您的应用程序没有处于高负载下,您就不需要过多关注它。

重要的是数据库引擎之间的锁定机制不同。如果您为一个数据库编写应用程序并在一段时间后更改数据库引擎,您的应用程序可能会表现不同,或者其中的某些部分可能需要重写。

我从 15 年的业务应用程序开发中得出的建议是不要依赖显式锁定。

于 2014-03-26T07:27:24.237 回答