sql - TSQL SELECT,然后在一个事务中进行UPDATE,然后返回SELECT

标签 sql tsql stored-procedures select coldfusion

我在ColdFusion应用程序(后端到MS SQL 2008)中的查询确实遇到麻烦。我在此事务中不断收到数据库死锁错误:

<code>
<cftransaction>
   <cfquery name="selectQuery">
      SELECT TOP 20 item_id, field2, field3
      FROM Table1
      WHERE subject_id = #subject_ID# AND lock_field IS NULL AND
            NOT EXISTS (SELECT * FROM Table2 WHERE Table2.user_ID = #user_ID# Table1.item_id = Table2.item_id)
   </cfquery>

   <cfquery name="updateQuery">
      UPDATE Table1
      SET lock_field = 1, locked_by = #user_ID#
      WHERE Table1.item_id IN (#ValueList(selectQuery.item_id#)
   </cfquery>
</cftransaction>
</code>

基本上,我有一个表(Table1),它代表大量等待项。用户“ checkout ”项目以给他们打分。一次只能有一个用户 checkout 一个项目。我需要为一个给定的用户一次请求20个项目的块。这些项目无法被 check out ,用户之前也不能对其进行评分(因此SELECT中的lock_field IS NULL和NOT EXISTS语句)。确定20个item_id的列表后,我需要更新队列表以将其标记为已锁定,因此没有其他人可以同时将它们 check out 。我还需要返回该item_ids列表。

我认为如果将它从cftransaction移到SQL Server端的存储proc上可能会更好。我只是不确定cftransaction锁定是否以某种方式干扰。我不是TSQL专家,所以需要一些帮助。

最佳答案

使用公用表表达式选择数据,然后更新CTE和UPDATE语句的输出。这样,所有操作都是一个单一的操作:

with cte as (
 SELECT TOP 20 item_id, field2, field3 
 FROM Table1 WITH (ROWLOCK, UPDLOCK)
 WHERE subject_id = #subject_ID# 
 AND lock_field IS NULL 
 AND NOT EXISTS (
   SELECT * FROM Table2 
   WHERE Table2.user_ID = #user_ID# AND Table1.item_id = Table2.item_id))
update cte   
 SET lock_field = 1, locked_by = #user_ID# 
 output inserted.item_id;

关于sql - TSQL SELECT,然后在一个事务中进行UPDATE,然后返回SELECT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1743686/

相关文章:

sql - 如何选择 col1 值 x 并复制到 col1 值 y 的新行,如果再次运行查询,不应再次复制

php - 根据条件连接不同的表

c# - ExecuteNonQuery 不返回值?

sql - 在 where in 子句中返回所有结果 (Sql Server)

sql - 如何在与子查询的连接中使用连接表中的列

Mysql 过程语法更改为 Firebird 过程语法

php - MYSQL 根据多行从表中选择

mysql - 使用外键进行双边行动

java - 参数 @x 没有为存储过程定义...使用 MS_SQL JDBC

c# - 为什么在集合中找不到 Mysql 存储过程参数?