仅在字段为True时更新SQL字段
我有一个通知表,其中包含id、type、user\u id和unseen列 要获取新的通知计数,我使用:仅在字段为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 但是这个更新查询有时会出错。我想知道,做这件事的正确方法是什么 编辑: 错误描
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按通知排序