技术开发 频道

.NET中锁6大处理方法 悲观乐观自己掌握

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

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

1

 图 6 timestamp数据类型

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

update tbl_items set itemname=@itemname where CurrentTimestamp=@OldTimeStamp

 

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

if(@@rowcount=0)
begin
raiserror(
'Hello some else changed the value',16,10)
end

 

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

1

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

  解决方案3:检查旧值和新值

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

update tbl_items set itemname=@itemname where itemname=@OldItemNameValue

 

  但使用乐观锁似乎没有完全解决问题,使用乐观锁只能检查并发性问题,为了从根源上解决并发性问题,我们需要使用悲观锁,因此乐观锁能起到预防作用,而悲观锁则能治愈。

  什么是悲观锁?

  悲观锁总是假定会发生并发性/冲突问题,因此会先对记录上锁,然后再更新。

1

图 8 悲观锁

  如何处理悲观锁?

  我们可以在SQL Server存储过程中指定IsolationLevel(隔离级别),ADO.NET级别或使用事务范围对象处理悲观锁。

  使用悲观锁可以获得什么样的锁?

  使用悲观锁可以获得四种类型的锁:共享(Shared)、独占(Exclusive),更新(Update)和意图(Intent),前两个是真实的锁,后面两个是锁和标记的混合。

 何时使用允许读允许写
共享锁当你只想读,不希望其它事务进行更新时
独占锁当你想修改数据,同时不希望别人可以读,直到你更新完毕时
更新锁这是一个混合锁,当你执行的更新操作有多个步骤时使用  
读阶段
操作阶段
更新阶段
意向锁(请求锁)意向锁是分级的,当你想锁定下级资源时使用,例如,在表上的一个共享意向锁意味着共享锁是针对页面和表中的行的,不适用不适用
模式锁当你修改表结构时使用
大数据块更新锁当你执行大数据块更新时使用表级(否)表级(否)

  

0
相关文章