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

我正在研究事务隔离级别,现在我有点困惑.看起来不同的事务隔离级别也可以解决类似的问题.

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

推荐答案

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

锁定可防止对某些对象使用concurrent access.例如,当您try 更新待办事项列表项时,使用悲观锁定,数据库会在记录上放置一个行锁,直到您提交或回滚事务,这样就不允许任何其他事务更新相同的记录.乐观锁定是应用程序端判断记录的时间戳/版本在获取和try 更新之间是否已更改.这与事务隔离级别无关.

事务隔离大约为read consistency.

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

请看下面的示例,我指出了不同事务隔离级别的查询结果.

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指定的事务隔离级别(上面的示例中没有提到的一个是"可重复读取"),除了可序列化之外,所有这些级别都会受到某些异常的影响.注意:它与锁定无关.

您可以查看关于这here的Oracle文档,其中的概念是相当通用的.

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

Database相关问答推荐

使用存储过程从子表中删除数据

SearchView 在 Android Studio 中显示 Data.entity.Cantact.@85c7ce6

如何将表字段的默认值设置为 0.00?

为什么引用 SQLite rowid 会导致外键不匹配?

将光标中找到的值输出到logcat?

Sql更新查询

在 Oracle 中查找数据库的大小

PostgreSQL Clob 数据类型

Android Room持久性库@Update不起作用

通过删除执行计划中的排序运算符来优化 SQL 查询

怎样有效存储 7.300.000.000 行?

NameError:设置更改为 mysql 后未定义名称_mysql

Neo4j:逐步创建自动索引

MySQL 转储所有数据库并在导入时创建(或重新创建)它们?

如何处理这个错误(1049,未知数据库'/users/ohyunjun/work/astral/mysql')

删除 PHP 中的所有小数

一个 Linq to Sql - 多个 .DBML 文件或一个 .DBML 文件

dbvisualizer:在 Select 查询中设置最大行数

使用 oracle sql developer 从一个数据库复制到另一个数据库 - 连接失败

获取 SQL Server 2008 中新插入行的主键