sql - 隔离级别和选择更新
问题描述
关系数据库的隔离级别和隔离级别之间有什么关系select for update
?
如果我使用与 SQL Server 的普通 JDBC 连接并将隔离级别设置为 READ_REPEATABLE 并使用简单的select
,我是否会看到可重复读取的不一致?或者我应该使用select for update
always 来避免事务中不一致的可重复读取?如果是这样,隔离级别的处理是什么,它们将如何发挥作用?
解决方案
SQL Server 没有select ... for update
语法。SQL Server 中的等价物是使用 UPDLOCK 表提示。
当读取一行并立即更新原子事务中的同一行时使用此提示。例如
declare @balance = (select balance from account where accountId = @id)
update account set balance = @balance + @amount where accountId = @id
在 READ COMMITTED 或任何没有多语句事务的隔离级别,多个会话可以运行第一个查询,并且在更新余额时丢失了更新。
使用 REPEATABLE READ 或 SERIALIZABLE 隔离级别将防止这种更新异常,但如果有任何并发事务已读取该行,并且如果其他事务之一尝试更新该行,它们会阻止第一个写入程序,从而导致僵局。
大多数情况下,这种行为不值得付出性能成本和处理死锁的烦恼。因此,您在读取时使用“select for update”(即 UPDLOCK)在行上放置 U 锁,并阻止后续读取器获取冲突锁。
例如
declare @balance = (select balance from account with (updlock) where accountId = @id)
update account set balance = @balance + @amount where accountId = @id
推荐阅读
- javascript - AssertionError [ERR_ASSERTION]: PORT 是必需的(将节点 js 作为 Windows 服务启动时)
- python - 如果当前列包含字符串,则检查其他列的值
- r - R中每第n列更改列名
- android - 任务的特定调度程序线程每个任务都应该有它自己的调度程序线程
- sql - 比较 Oracle SQL 中属性的所有条目
- javascript - 有没有办法使用 Moment.js 计算给定年份的 ISO 周数?
- c# - 更新/删除记录时如何处理多对一关系
- flutter - Flutter - 在构建器内部的开关内调用导航器
- bash - 在file2中找到离file1最近的点,shell skript
- python - 如何用python在图像中找到一个矩形?