在SQL中安全地更新计数(字段)

5 sql concurrency

我想在userpost上实现类似标签的SO.我有一个名为tag_data的表,其中包含tagId,title,count.我有一个单独的表链接帖子和它可能使用的许多标签之间的关系.

这是问题所在,如何获得当前计数,将其增加或减少一个并将其保存为SAFELY.所以没有其他连接/线程会在我选择和更新之间更新它吗?

Rem*_*anu 14

我假设你也想要新的计数,其他明智的这是一个没脑子,只需更新set count = count + 1.

如果UPDATE上的db support输出子句(例如SQL Server 2K5或2K8):

UPDATE table
   SET count = count + 1
   OUTPUT inserted.count
   WHERE id=@id;
Run Code Online (Sandbox Code Playgroud)

除此以外:

begin transaction
update table 
    set counter=counter+1
    where id=@id;
select counter
    from table
    where id=@id;
commit;
Run Code Online (Sandbox Code Playgroud)

  • 更新获得的X锁是在事务持续时间*的帮助*,并阻止其他人读取或更新计数器,直到您提交.这为您提供了一个保存位置来进行选择,因为您知道您将检索更新的实际值.在Mikey的情况下,语句完成后(在正常情况下),select选取的S锁是*not*help,因此允许第二个线程潜入并在执行更新时更新值,并且您将覆盖那次更新.因此'丢失更新'. (3认同)
  • 好答案.我对两件事感到困惑.看起来update/select是一个声明,那你为什么需要一个交易呢?第二个是通过另外两个响应判断,似乎事务将锁定数据库直到它完成,那么MikeyB为什么回答不好?我读了你的回复,但是会发生什么?,其他线程可以在事务中读取但不能写入? (2认同)