[英]Row locks on select
我有一个存储过程,它执行以下操作:
以下是我在Sybase ASE中的工作方式:
set rowcount @count
begin tran get_items
insert into #temp_table
select item
from available_item
where is_processed = 0
update available_item
set is_processed = 1
from available_item, #temp_table
where available_item.item = #temp_table.item
# select the processed items...
commit trans
我想知道这里是否有竞争条件。 如果两个单独的进程同时执行此存储过程,它们是否可以选择并标记处理相同的数据? 或者在交易中有这个停止吗?
如果没有,有没有办法在选定的行上持有锁?
一些细节将取决于您的表锁定方案。 所有页面,页面和行级别锁定将对您在单个表上运行并发更新的能力产生不同的影响。 我假设一个页/行级方案,以允许并发。
您的查询将获取一个初始共享页面/行锁定,该锁定将升级到更新锁定,然后在更新的页面/行上进行独占行锁定。 在事务期间,没有其他进程能够对所选页面/行进行更改,但是另一个进程可能会在更新之前读取所选行,这可能会导致一些不一致。
要绕过这种可能性,可以将事务中的隔离级别指定为隔离级别2(可重复读取)或隔离级别3(序列化)。 您可能希望了解每个级别的具体细节,以确定要强制执行的内容,以及与之相关的权衡。
在您的交易中,您可以像这样使用它:
set rowcount @count
set transaction isolation level 2
...
需要注意的是,根据您在查询中获取的记录数量,您可以触发锁升级,这可能会阻止并发事务执行,即使它们没有查看与第一个事务相同的行。 默认情况下,如果服务器获取超过200页/行的锁,则服务器将尝试升级到表锁。 这可以更改为显式值或值范围和百分比,并且可以在服务器,数据库或表级别进行配置。
相关文件:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.