我正在编写一个Web应用程序,两个不同的用户可以更新事项列表,例如待办事项。我已经意识到,乐观锁定机制最适合我,因为我不希望高并发。
我正在研究事务隔离级别,现在有点困惑了。看起来不同的事务隔离级别也可以解决类似的问题。
这两个不同的概念如何相关?如果可能,请给出一个简单的例子。
我正在编写一个Web应用程序,两个不同的用户可以更新事项列表,例如待办事项。我已经意识到,乐观锁定机制最适合我,因为我不希望高并发。
我正在研究事务隔离级别,现在有点困惑了。看起来不同的事务隔离级别也可以解决类似的问题。
这两个不同的概念如何相关?如果可能,请给出一个简单的例子。
这两件事情都涉及数据一致性和并发访问,但它们是两种不同的机制。
锁定防止某个对象被同时访问。例如,当您尝试更新待办事项列表项时,使用悲观锁定数据库会在记录上放置行锁,直到您提交或回滚事务为止,以便不允许其他事务更新相同的记录。乐观锁定是应用程序端检查在获取和尝试更新记录之间时间戳/版本是否已更改。这与事务隔离级别无关。
事务隔离级别是关于读取一致性的。
请看下面的例子,我指出了查询结果在事务隔离级别之间的差异。
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请求中获取并更新列表项。在提取后显式锁定记录并保持事务不变是不可能的(您怎么知道第二个请求会到达吗?)乐观锁处理得很好。
锁定机制通常用于实现事务隔离级别。因此,事务隔离级别定义了您的事务在并发执行中必须如何行为的合同。锁定机制是实现细节。
从应用程序编写的角度来看,您应该专注于设置适当的事务隔离级别。当然,设置特定的隔离级别意味着锁定,但只要您的应用程序没有承受重负载,您就不需要太关心它。
重要的是,锁定机制在数据库引擎之间有所不同。如果您为一个数据库编写应用程序,并且一段时间后更改了数据库引擎,则您的应用程序可能会表现出不同的行为或某些部分可能需要重新编写。
我在业务应用程序开发方面的建议是不要依赖显式锁定。