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

仅在字段为True时更新SQL字段,sql,sql-server,database,Sql,Sql Server,Database,我有一个通知表,其中包含id、type、user\u 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 但是这个更新查询有时会出错。我想知道,做这件事的正确方法是什么 编辑: 错误描

我有一个通知表,其中包含id、type、user\u 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
但是这个更新查询有时会出错。我想知道,做这件事的正确方法是什么

编辑:

错误描述
事务(进程ID 68)被锁定;与另一进程的通信缓冲区资源,并已被选为死锁牺牲品。重新运行事务

在“更新”中,您应该使用诸如记录的Primery键之类的东西来标记您看到的记录

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

这可能是死锁问题,当您试图更新记录时,有些人也在读取这些记录

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

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

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

下面的语句将忽略锁定的记录和未限制的记录

SELECT count(1) FROM notifications (NOLOCK) WHERE user_id=123 AND unseen=1
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
因此,使用readpass和ROWLOCK提示,可以避免死锁


您说的“此更新查询有时会出错”是什么意思?哪个错误?这会将未看到的用户的所有通知更新为false。您应该提到一些通知唯一代码,以便只更新所需的代码。虽然在某些情况下可能是这样,但在所有情况下都不是这样。此外,海报提交的是有效的SQL,因此不应导致错误。实际上,这两个查询会导致死锁。>从通知中选择TOP 20*,其中user_id=123按通知排序\u id DESC和UPDATE notifications SET unseen=0,其中user_id=123和unseen=1在您的场景中,在读取记录时只需使用NOLOCK。从通知(NOLOCK)中选择前20个*,其中用户id=123按通知排序