仅在字段为True时才更新SQL字段

时间:2012-05-03 05:51:02

标签: sql sql-server database

我有一个包含id,type,user_id和unseen列的通知表。

要使用新的通知计数:

SELECT count(1) 
FROM notifications 
WHERE user_id=123 AND unseen=1

仅标记我使用的新通知:

UPDATE notifications 
SET unseen=0 
WHERE user_id=123 AND unseen=1

但是此更新查询有时会出错。我想知道,这样做的正确方法是什么?

编辑:

  

ERROR DESC
  交易(进程ID 68)在锁定时陷入僵局;与另一个进程通信缓冲资源并被选为死锁牺牲品。重新运行该交易。

3 个答案:

答案 0 :(得分:0)

它可能是死锁的问题,当你试图更新记录时,有些人也在阅读这些记录。

您的更新语句是一个完整的声明,我认为它没有在事务中运行。看来,您希望获得更多优先级来完成更新的语句而不是读取语句(使用select)。

对于上述场景,您可以在阅读时使用NoLock允许幻像读取(每次用户使用时执行选择查询获得不同的输出)。在您的场景中,它不会是脏读,因为您将只读取提交的记录。

SELECT count(1) FROM notifications (NOLOCK) WHERE user_id=123 AND unseen=1

答案 1 :(得分:0)

以下语句将忽略锁定的记录和未提交的记录。

SELECT count(1) 
FROM notifications WITH(READPAST)  
WHERE user_id=123 AND unseen=1

以下语句将锁定需要更新的记录,它不会锁定整个表。

UPDATE notifications  with (ROWLOCK) 
SET unseen=0 
WHERE user_id=123 AND unseen=1

因此,使用READPAST和ROWLOCK提示,可以避免死锁。

Read from her to know about READPAST and NOLOCK

答案 2 :(得分:-1)

在“更新”中,您应该使用记录的Primery键之类的内容标记您所看到的记录。

UPDATE notifications SET unseen=0 WHERE user_id=123 AND unseen=1 and PKID='some thing'