在 SQL 服务器中管理并发

Manage concurrency in SQL Server

我的 SQL 服务器数据库中有一个 table,其中包含一些关于书籍的数据,如下面给定的屏幕截图:

+----+-------+-------+--------+
| Id | Title | Price | Status |
+----+-------+-------+--------+
|  1 | C#6   | 40.00 |      0 |
+----+-------+-------+--------+

Status栏表示图书可借(0=可用,1=已借)

假设有 2 个或更多用户在我的 Web 应用程序中看到了这本书,并且这些用户同时试图借这本书,如果不管理并发性,我们将为除用户之外的其他用户获得异常# 1.

我知道我们可以使用 SQL 事务和像 Serializable 这样的隔离级别来确保没有更多的用户同时使用同一条数据,但是在这里,我有几个问题:

  1. 这是这种情况的最佳做法吗?如果没有,请分享您的建议。
  2. 如果是这样,其他用户怎么办?在用户#1 借到书后他们应该得到什么?还有,在最终确认之后还是在最终确认之前在最终级别处理并发好吗?

这种情况下的最佳做法是乐观并发。在 table 中添加一个 rowversion 列,并在更新时检查该值是否与原始值发生变化:

CREATE TABLE dbo.Book(
      Id int NOT NULL CONSTRAINT PK_book PRIMARY KEY
    , Title varchar(30) NOT NULL
    , Price decimal(9,2) NOT NULL
    , Status bit NOT NULL
    , row_version rowversion NOT NULL
    );

INSERT INTO dbo.Book (Id, Title, Price, [Status])
    VALUES(1, 'C# 6', 40.0, 0);
GO


CREATE PROC dbo.UpdateBookAvailability
      @Id int
    , @Rowversion rowversion
    , @Status bit
AS
UPDATE dbo.Book
SET Status = @Status
WHERE
    Id = @Id
    AND row_version = @RowVersion;
IF @@ROWCOUNT < 1
BEGIN
    RAISERROR('book not avaiable', 16, 1);
END;
GO