SQL 服务器 "update" - 是否存在竞争条件?
SQL Server "update" - is there a race condition?
我有一个 table,我想在其中处理给定 ID 的按需记录。我只想处理每条记录一次(当客户端请求时)。
update my_table set pending_flag = 1 where my_table_id = 33 and pending_flag = 0
当我 运行 这个查询时,它 return 受影响的记录数,1
或 0
。
可以安全地假设 运行 宁此查询只会 return 1
最多 1 次吗?如果是这样,我可以单独使用这个命令作为一种机制来保证我不会多次处理记录吗?
其他详细信息:
pending_flag
永远不会设置回 0
可能涉及多个线程(一如既往)
如果将pending_flag
设置为1的过程没有完成,那个ID本质上停留在"pending"状态,永远搞砸了,那就是acceptable(但不理想)
如果 my_table_id
是您的 table 的主键(即设置了主键约束),那么确实不可能有 2 行受该更新语句影响。
通过锁定,数据库引擎确保一行由一个进程一次更新。在任何时候都不会出现两条具有相同 my_table_id
值的记录,因为主键约束禁止这种情况。
其次,当您将标志 pending_flag
更新为 1 时,如果您再次 运行 相同的 update
语句,则记录将不匹配,因此将更新 0 条记录.
can I use this command alone as a mechanism to guarantee that I don't process the record multiple times?
是的! (条件是您将 my_table_id
作为主键或至少具有唯一约束)。
我看不到 sql 服务器端的任何保证。没有什么可以阻止意外或程序错误将此标志设置回 0。您可能希望添加一个触发器,在标志设置为 1 时禁止更新标志。
目前唯一的服务器保证是只有一个尝试设置 0 -> 1 的并发进程会成功。
我有一个 table,我想在其中处理给定 ID 的按需记录。我只想处理每条记录一次(当客户端请求时)。
update my_table set pending_flag = 1 where my_table_id = 33 and pending_flag = 0
当我 运行 这个查询时,它 return 受影响的记录数,1
或 0
。
可以安全地假设 运行 宁此查询只会 return 1
最多 1 次吗?如果是这样,我可以单独使用这个命令作为一种机制来保证我不会多次处理记录吗?
其他详细信息:
pending_flag
永远不会设置回0
可能涉及多个线程(一如既往)
如果将
pending_flag
设置为1的过程没有完成,那个ID本质上停留在"pending"状态,永远搞砸了,那就是acceptable(但不理想)
如果 my_table_id
是您的 table 的主键(即设置了主键约束),那么确实不可能有 2 行受该更新语句影响。
通过锁定,数据库引擎确保一行由一个进程一次更新。在任何时候都不会出现两条具有相同 my_table_id
值的记录,因为主键约束禁止这种情况。
其次,当您将标志 pending_flag
更新为 1 时,如果您再次 运行 相同的 update
语句,则记录将不匹配,因此将更新 0 条记录.
can I use this command alone as a mechanism to guarantee that I don't process the record multiple times?
是的! (条件是您将 my_table_id
作为主键或至少具有唯一约束)。
我看不到 sql 服务器端的任何保证。没有什么可以阻止意外或程序错误将此标志设置回 0。您可能希望添加一个触发器,在标志设置为 1 时禁止更新标志。
目前唯一的服务器保证是只有一个尝试设置 0 -> 1 的并发进程会成功。