更新事务中的选定行

时间:2012-10-20 23:05:47

标签: .net sql transactions transactionscope

我有一个自动化项目,有一个远程数据库(MsSql)和多个Windows / Web客户端。客户端应用程序检查并选择表上合适的行,并将其标记为保留用于在该行上操作。

  1. 如何在另一个客户选择同一行之前轻松获取值并更新所选行?我有什么选择?
  2. 如果我想在事务块内部执行多个select-update语句(对于不同的表),我可以使用TransactionScope吗?
  3. 编辑: 让我们想象一下电影票系统(我的电视票有点复杂)。用户选择座位并购买票证。我想为这位用户预留座位两分钟,以便有足够的时间购买。两分钟后,其他人也可以使用。在更新行之前,我运行一个select查询来查找第一个空座位。我的问题是在同一用户的select和update语句之间花了一点时间。我想阻止:User1的select语句运行,此时User2在User1保留座位之前运行相同的选择。

2 个答案:

答案 0 :(得分:2)

由于您希望在锁定和执行实际操作之间进行用户输入,因此

update top (1) seats
set time_locked = getdate(), user_locked = <the site user>
output inserted.seat_id, inserted.time_locked, inserted.user_locked
where <your conditions> and time_locked is null

在这种情况下,您不会在执行此操作之前启动事务,因为您希望立即提交更改。您可以在以后锁定行或稍后的某个时间打开转换。

如果从事务中执行此操作,则其他进程将等待您提交该事务,因此您将无法获得任何并发。您将看到的是,一个流程正在运行,其他所有流程都在等待。

当您稍后返回锁定行时,验证time_locked仍为非空,并且锁定的用户是同一用户:

update seats
set totally_taken = 1
where
  seat_id = <remembered seat id>
  and time_locked = <remembered time_locked>
  and user_locked = <remembered user_locked>

答案 1 :(得分:0)

如果您使用的是SQL Server,则可以在选择中执行ROWLOCK。

  

SELECT * FROM ORders WITH ROWLOCK WHERE Status ='Pending'