技术详解:三招优化.NET中的锁(组图)

开发 后端
在多用户环境中,大家同时更新相同的记录可能会引发冲突,这个问题用专业的术语描述就叫做并发性。并发会造成什么样的冲突?并发主要会导致四种常见的问题。

在这篇文章中,我将使用三个方法处理乐观锁,包括ADO.NET数据集、SQL Server时间戳数据类型和新旧值检查,首先我们从并发谈起,探讨5个并发问题,然后从实际出发,利用这三种方法实现乐观锁。

为什么需要锁?
在多用户环境中,大家同时更新相同的记录可能会引发冲突,这个问题用专业的术语描述就叫做并发性。并发会造成什么样的冲突?并发主要会导致四种常见的问题,详细情况请看下表。


如何解决上述冲突?
答案是使用乐观锁或悲观锁,下面将进一步进行阐述。什么是乐观锁?顾名思义,乐观锁假设多个事务相互不会影响对方,换句话说就是,在乐观锁模式下,没有锁操作会得到执行,事务只是验证是否有其它事务修改数据,如果有则进行事务回滚,否则就提交。

乐观锁是如何工作的?
1、实现乐观锁的方法有多种,但基本原则都一样,总是少不了下面五个步骤:
2、记录当前的时间戳
3、开始修改值
4、在更新前,检查是否有其他人更新了值(通过检查新旧时间戳实现)
5、如果不相等就回滚,否则就提交
 


图 1 乐观锁的工作原理

实现乐观锁的解决方案

在.NET中,实现乐观锁的方法主要有三种:
1、数据集(Dataset):数据集是实现乐观锁的默认方法,在更新前它会检查新旧值。
2、时间戳数据类型(timestamp):在你的表中创建一个timestamp数据类型,在更新时,检查旧时间戳是否等于新时间戳。
3、直接检查新旧值:在更新时检查旧值和新值是否相等,如果不相等就回滚,否则就提交。

解决方案1:数据集
正如前面所说的,数据集是处理乐观锁的默认方法,下面是一个简单的快照,在Adapter的update函数上有一个调试点,当我移除断点运行update函数时,它抛出如下图所示的并行异常错误。
 


图 2 Update函数执行时抛出的异常错误

如果你运行后端分析器,你将会看到更新语句检查当前值和旧值是否相等:


在这种情况下,我尝试将“AuthorName”字段值修改为“This is new”,但更新时会检查旧值“This is old author”,下面是比较旧值的精简代码段:


解决方案2:使用timestamp数据类型

SQL Server有一个数据类型是timestamp,它是实现乐观锁的另一种途径,每次更新SQL Server数据时,时间戳会自动产生一个***的二进制数值,时间戳数据类型可用来版本化你的记录更新。


图 3 timestamp数据类型

为了实现乐观锁,首先需要取得旧的时间戳值,在更新时检查旧的时间戳值是否等于当前时间戳,如:


然后检查是否发生了更新操作,如果没有发生更新,则使用SQL Server的raiserror产生一系列错误消息。
 

如果发生了并发冲突,当你如下图所示这样调用ExecuteNonQuery时,你应该会看到错误传播。


图 4 时间戳发生变化,存储过程产生了错误

解决方案3:检查旧值和新值
许多时候,我们只需要检查相关字段值的一致性,其它字段则可以忽略,在update语句中,我们可以直接做这种比较。

 

责任编辑:马沛 来源: 51CTO.com
相关推荐

2009-08-13 17:25:16

2009-10-12 09:02:03

SmartRWLock

2020-01-16 14:59:32

Java锁优化CAS

2009-02-18 16:34:32

优化Windows启动时间

2009-12-09 14:11:57

Visual Stud

2010-03-16 16:56:45

云计算

2012-06-14 09:09:43

微软Windows 8视频

2023-06-02 08:29:24

https://wwMutex

2013-03-22 09:25:59

VCF虚拟化

2009-02-17 17:42:57

服务器虚拟化虚拟化VMware

2009-07-28 13:48:28

ASP.NET树形图

2009-07-09 09:28:19

.Net Micro

2019-01-04 08:00:59

Linux硬件容器

2009-03-09 17:30:42

.NET FramewXMLXmlReader

2009-11-13 15:33:58

ADO.NET数据对象

2009-08-04 15:02:18

ASP.NET数据验证

2009-03-13 13:46:41

.NETServer push服务端

2010-01-07 15:57:02

VB.NET ForEach

2009-08-13 11:44:25

ASP.NET中的多种

2009-12-04 09:14:05

.NET 4.0
点赞
收藏

51CTO技术栈公众号