SQL Server“更新” - 是否存在竞争条件?

时间:2016-05-24 15:21:43

标签: sql sql-server race-condition

我有一个表格,我希望根据其ID来按需处理记录。我只想处理每个记录一次(当客户请求时)。

class myArrayThread(threading.Thread): def __init__(self,ThreadName, func): self.ThreadName = ThreadName self.myfunction = func # ......... more stuff after this

当我运行此查询时,它会返回受影响的记录数,update my_table set pending_flag = 1 where my_table_id = 33 and pending_flag = 01

是否可以安全地假设运行此查询最多只会返回0 1次?如果是这样,我可以单独使用此命令作为保证我不多次处理记录的机制吗?

其他详情:

  • 1永远不会被设置回pending_flag

  • 可能涉及多个线程(一如既往)

  • 如果将0设置为1的进程未完成,并且该ID基本上处于“挂起”状态并且永远搞砸了,那么这是可以接受的(但不是理想的)

2 个答案:

答案 0 :(得分:3)

如果my_table_id是表的主键(即设置了主键约束),那么确实不可能有2行受该更新语句的影响。

通过锁定,数据库引擎确保一次一个进程更新一行。在任何时候,my_table_id都会有两个具有相同值的记录,因为主键约束禁止这种情况。

其次,当您将标志pending_flag更新为1时,如果再次运行相同的update语句,则记录将不匹配,因此0记录将被更新。

  

我可以单独使用此命令作为一种机制来保证我不会多次处理记录吗?

是的! (条件是您有my_table_id作为主键或至少具有唯一约束条件。)

答案 1 :(得分:1)

我在sql server端看不到任何保证。什么都不能防止意外或程序错误将此标志设置为0。您可能希望添加一个触发器,当该标志设置为1时,该触发器禁止对标志进行任何更新。

目前唯一的服务器保证是只有一个并发进程尝试设置0 - > 1将成功。