不可重复从SQL Server

时间:2015-07-09 08:13:28

标签: sql sql-server

假设我有一个表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行,但是锁定应该跳过第一个请求的行,即使在两个请求的同时选择语句期间

请帮我解决这个问题。

2 个答案:

答案 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
}

ISOLATION LEVELS on MSDN

  

REPEATABLE READ"指定语句无法读取具有的数据   已被修改但尚未由其他交易提交   没有其他事务可以修改已被读取的数据   当前事务直到当前事务完成。"