ste*_*tej 9 sql sql-server nhibernate concurrency
我需要在数据库中首先选择(比方说)10000行并返回它们.可能有更多客户端同时执行此操作.我提出了这个问题:
update v set v.batch_Id = :batchId
from tblRedir v
inner join (
select top 10000 id
from tblRedir
where batch_Id is null
order by Date asc
) v2 on v.id=v2.id
Run Code Online (Sandbox Code Playgroud)
它是一个由更新和嵌套选择组成的操作.两个查询都在同一个表(tblRedir)上工作.这个想法是行首先由唯一的batchId标记,然后通过返回
select * from tblRedir where batch_id = :batchId
Run Code Online (Sandbox Code Playgroud)
(batchid是每个此更新的唯一标识符(例如,时间戳或guid))
我的问题:
我认为嵌套select的操作更新是原子的 - 这意味着每个客户端都会收到他自己的唯一数据集(没有其他客户端收到他的数据子集).
但是它看起来是我错了-在某些情况下是没有收到数据的客户,因为他们很可能首先都执行选择和那么这两个执行更新(所以第一个客户端没有明显的行).
这个操作是原子的吗?
我使用Sql server 2005.查询是通过NHibernate运行的
session.CreateSQLQuery('update....')
Run Code Online (Sandbox Code Playgroud)
SELECT
在读取的行上放置共享锁,然后可以在READ COMMITED
隔离模式下解除.
UPDATE
将更新锁稍后提升为独占锁.直到交易结束才取消它们.
您应该在锁定后立即保留锁定.
您可以通过创建事务隔离级别来执行此操作,该级别REPEATABLE READ
将保留共享锁直到事务结束并且将阻止UPDATE
部件锁定这些行.
或者,您可以重写您的查询:
WITH q AS
(
SELECT TOP 10000 *
FROM mytable WITH (ROWLOCK, READPAST)
WHERE batch_id IS NULL
ORDER BY
date
)
UPDATE q
SET batch_id = @myid
Run Code Online (Sandbox Code Playgroud)
,它将跳过锁定的行.
归档时间: |
|
查看次数: |
2891 次 |
最近记录: |