您描述的是标准并发控制问题。在 Web 开发的情况下,通常使用乐观并发控制来解决问题。作为 ASP.NET 开发人员,您可能使用 Microsoft SQL Server 来保存数据。SQL Server 支持非常有用的数据行版本类型(也称为timestamp
数据类型)。不可为空的rowversion
列在语义上等同于binary(8)
列。使用的主要优点是使用rowversion
简单。SQL Server 支持与数据库关联的内部计数器。每个@@DBTS
变量都可以访问计数器。每次修改数据库表中的一行时,该rowversion
列将自动更改的值,@@DBTS
并将@@DBTS
递增。可以使用附加rowversion
列轻松确定自上次读取以来该行中的任何值是否已更改。
因此,如果您有一个现有的数据库表,您只需添加一列来保存行更新计数器的行版本(时间戳)。例如语句
ALTER TABLE dbo.Users ADD RowUpdateTimeStamp rowversion NOT NULL
将RowUpdateTimeStamp
类型的列添加rowversion
到表中dbo.Users
。如果您创建新的用户表,您可以执行以下操作
CREATE TABLE dbo.Users (
Id int NOT NULL IDENTITY,
FirstName nvarchar(64) NOT NULL,
LastName nvarchar(64) NOT NULL,
RowUpdateTimeStamp rowversion NOT NULL,
CONSTRAINT PK_Users PRIMARY KEY CLUSTERED (Id ASC),
CONSTRAINT UC_Users_LastName_FirstName UNIQUE NONCLUSTERED (LastName ASC, FirstName ASC)
)
它会创建您描述的表,但该表将具有额外RowUpdateTimeStamp
的类型列rowversion
。再次强调,不需要手动在列中保存任何值,这一点很重要。SQL Server 将自动保存/修改列的值。
如果您使用表中的数据填充网格,例如,您可以将隐藏列包含在数据库表列中RowVersion
的值中。RowUpdateTimeStamp
中对应列的定义colModel
如下
name: "RowVersion", sortable: false, hidden: true, hidedlg: true,
editable: true, editrules: { edithidden: false }
这意味着隐藏的值RowVersion
将与另一个可编辑列的值一起发送。
修改网格行的服务器方法返回修改后的RowUpdateTimeStamp
. 我使用内联编辑或表单编辑的aftersavefunc
回调来使用从服务器返回的值修改网格的列。afterSubmit
RowVersion
如果服务器从客户端接收到修改请求,它总是RowVersion
在修改行。服务器代码验证数据库中相应数据的列值是否小于或相等
RowUpdateTimeStamp
。如果数据库具有更高的价值,那么另一个用户已经修改了数据。如果服务器返回带有一些错误 HTTP 代码 (>=300) 的 HTTP 响应。jqGrid 将响应解释为错误并显示相应的错误消息。可以使用errorTextFormat或errorfunc来自定义错误消息。
我在所有生产实现中使用上述方法。您可以在旧答案中阅读有关该主题的其他信息。