假设我有一个表100行,我只想选择前10行表,但我的情况是我想只选择那些以前没有处理过的行。 为此,我添加了一个Flag列,以便每当我处理行时都会更新。
但是,当并发请求进入前10行时,问题就出现了。两者都可能获得相同的行并尝试更新相同的行(我不想这样做)。
我不能使用Begin Transaction,因为它会锁定表,并且不会处理并发请求。
要求:我的实际要求是当我选择前10行时 使用标志条件并更新然后,如果其他请求 同样它也会选择其他未处理的前10行 要求1。
Example : My table contains 100 rows.
{
Select top 10 * from table_name where flag=0
update table_name set top 10 flag = 1
}
(Will select top 10 out of 100 rows n update)
if at the same time during above request, another request come,
{
Select top 10 * from table_name where flag=0 (Should skip previous request rows)
update table_name set top 10 flag = 1
}
Need: (Will select top 10 out of rest 90 rows n update)
我需要锁定第一个请求的前10行,但是锁定应该跳过第一个请求的行,即使在两个请求的同时选择语句期间
请帮我解决这个问题。
答案 0 :(得分:1)
您可以使用OUTPUT子句在一个语句中同时选择和更新标志,例如
UPDATE TOP 10 table
SET flag = 1
WHERE flag = 0
OUTPUT inserted.*
答案 1 :(得分:0)
如果我理解正确,您不想使用交易,因为它会在更新期间锁定表格。
也许您可以将流程拆分为一个选择行并更新标志的部分,以及第二个部分,您实际使用所选行进行更新。
仅对任务的第一部分使用交易。这将确保表仅在绝对最短时间内被锁定。
至于你的不可重复的读物:
如果您确实要强制执行此策略,则应从表中删除所选行,并可选择将它们保存到读取历史记录所在的另一个表中。实现这一目标的最低级别方法是更新另一个标志(更新?)和更新后的触发器。
Transaction with ISOLATION LEVEL REPEATABLE READ
{
select top 10 rows
update select-flag
return the 10 rows
}
normal query
{
take the returned 10 rows and do something
change updated-flag
}
Trigger after update if updated-flag changed
{
copy updated to read-history-table
delete updated-rows
}
REPEATABLE READ"指定语句无法读取具有的数据 已被修改但尚未由其他交易提交 没有其他事务可以修改已被读取的数据 当前事务直到当前事务完成。"