介绍
对于那些只允许用户查看数据或者只有一个用户可以修改数据的web应用,不存在多用户并发冲突的问题。但是,对于允许多个用户修改或删除数据的web应用程序,一个用户所做的更改可能会与另一个并发用户所做的更改相冲突。在没有并发策略的情况下,当两个用户同时编辑一条记录时,最后提交的用户的更改将覆盖第一个提交的用户所做的更改。
例如,假设两个用户,季孙和萨姆,访问我们应用软件中的一个页面,该页面允许访问者通过一个GridView控件更新和删除产品数据。他们都同时单击了GridView控件中的“编辑”按钮。季孙将产品名称改为“柴茶”,并点击了“更新”按钮。真正的结果是向数据库发送一条UPDATE语句,该语句将更新该产品的所有可修改字段(尽管季孙实际上只修改了一个字段:产品名称)。
此时,数据库包含产品记录“柴茶”——类别是饮料,供应商是外来液体,等等。然而,在山姆屏幕上的GridView中,当前编辑行中显示的产品名称仍然是“柴”。季孙的更改提交后不久,萨姆将类别更改为“调味品”,并单击了“更新”按钮。发送到数据库的UPDATE语句的结果是产品名称更改为“柴”,CategoryID字段的值是与饮料类别对应的ID,以此类推。季孙对产品名称所做的更改将被覆盖。图1显示了这些连续的事件。
图1:当两个用户同时更新一条记录时,一个用户的更改可能会覆盖另一个用户的更改。
同样,当两个用户同时访问一个页面时,一个用户可能会更新另一个用户已删除的记录。或者,在用户加载页面和单击删除按钮之间的时间内,另一个用户修改了该记录的内容。有三种并发控制策略可供选择:
1.什么也不做如果并发用户修改了相同的记录,让最终提交的结果生效(默认行为)。2.乐观并发——假设并发冲突只是偶尔发生,大多数情况下不会发生;然后,当发生冲突时,只需通知用户他的更改无法保存,因为其他用户已经修改了相同的记录。3.悲观并发——假设并发冲突经常发生,用户不能容忍被告知由于他人的并发行为而无法保存自己的更改;然后,当用户开始编辑记录时,锁定该记录,以防止其他用户编辑或删除该记录,直到他完成并提交自己的更改。
注意:在本节中,我们将不讨论保守附件的示例。保守并发控制很少使用,因为如果锁没有完全释放,会阻止其他用户更新数据。例如,如果用户锁定记录进行编辑,但在解锁之前离开,则在原始用户返回并完成更新之前,其他用户无法更新该记录。因此,在使用保守并发控制的情况下,将相应地设置时间限制,如果达到该时间限制,将取消锁定。例如,预订网站会在用户完成预订过程时锁定特定的座位,这是使用保守并发控制的一个例子。
步骤:如何实现开放式并发控制。
开放并发控制可以确保当记录被更新或删除时,它与它开始更新或修改过程时是一致的。例如,当您在可编辑的GridView中单击“编辑”按钮时,记录的原始值将从数据库中读取,并显示在文本框和其他网络控件中。这些原始值存储在GridView中。然后,当用户完成修改并单击“更新”按钮时,这些原始值加上修改后的新值被发送到业务逻辑层,然后发送到数据访问层。数据访问层必须发出一条SQL语句,该语句将只更新那些在编辑开始时根数据库中原始值一致的记录。图2描述了这些事件的顺序。
图2:为了更新或删除成功,原始值必须与数据库中的相应值一致。
实现开放并发控制的方法有很多(参见Peter A. Bromberg的文章opt wrong concurrency updating logic,并在摘要中看到很多选择)。ADO.NET类型的数据集提供了一个应用程序,它只需要在配置过程中检查前面的复选框。开发并发性的目的是使类型化数据集的TableAdapter的UPDATE和DELETE语句能够检测数据库中的值自记录加载到数据集中以来是否已被更改。例如,当当前数据库中的值与GridView中编辑的原始值一致时,以下UPDATE语句会更新产品的名称和价格。@ProductName和@UnitPrice参数包含。