我对Jqgrid行更新有疑问。我们有一个如下所示的数据库表。
id:1 field1:john field2:black
想象一下,用户想要更新第一行,其中有一个名为id = 1的字段。用户双击该行并打开该行的详细信息。如您所见,第一行field1是john,field2是黑色。 如果另一个用户在第一个用户之后双击同一行并将field2更新为红色,会发生什么?第一个用户仍在更新屏幕上。在他的屏幕上,field2仍然是黑色的。之后,第一个用户只将field1更新为jack并保存该行。结果将是field1:jack,field2:black。因为第一个用户不知道field2的变化。并且第二个用户的field2更改已经消失.. 如何防止此示例中的数据丢失?
我在用户双击时更新所有字段并保存行中的任何更改。 提前致谢
答案 0 :(得分:2)
您所描述的是标准concurrency control问题。在Web开发的情况下,通常使用optimistic concurrency control来解决问题。作为ASP.NET开发人员,您可能使用Microsoft SQL Server来保存数据。 SQL Server支持非常有用的数据类型rowversion(也称为timestamp
数据类型)。不可为空的rowversion
列在语义上等同于binary(8)
列。使用rowversion
的主要优点是使用简单。 SQL Server支持与数据库关联的内部计数器。计数器可以按@@DBTS
变量访问。每次修改数据库表格中的一行时,rowversion
列都会自动更改为<{1}},@@DBTS
会增加@@DBTS
。可以使用其他rowversion
列轻松确定自上次读取以来该行中的任何值是否发生了更改。
因此,如果您有一个现有的数据库表,您只需添加一列,该列将保存行更新计数器的rowversion(时间戳)。例如声明
ALTER TABLE dbo.Users ADD RowUpdateTimeStamp rowversion NOT NULL
会将RowUpdateTimeStamp
类型的rowversion
列添加到表格dbo.Users
。如果您创建新的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
的修改版本。我使用inline editing的aftersavefunc
回调或form editing的afterSubmit
来修改网格的RowVersion
列,并使用从服务器返回的值。
如果服务器收到来自客户端的修改请求,则它始终是修改行的RowVersion
。服务器代码验证数据库中的相应数据是否具有较小或相等的值
RowUpdateTimeStamp
列。数据库具有更高的值,然后另一个用户已经修改了数据。在服务器返回带有错误HTTP代码的HTTP响应的情况下(&gt; = 300)。 jqGrid将响应解释为错误并显示相应的错误消息。可以使用errorTextFormat或errorfunc来自定义错误消息。
我在所有高效实现中使用上述方法。您可以在the old answer中阅读有关该主题的其他信息。