数据锁定避免脏数据

今年团购、秒杀网站出现的比较多,本文主要是针对秒杀类型的网站网,它数据并发的可能性很大。如果不采用数据库锁的概念。用户最终卖出的商品很有可能比预计的要多的多。(数据库锁的概念并不是解决这一问题的最好的办法)多个用户同时对数据库的并发操作时会带来以下数据不一致的问题:

丢失更新

A,B两个用户读同一数据并进行修改,其中一个用户的修改结果破坏了另一个修改的结果,比如订票系统

脏读

A用户修改了数据,随后B用户又读出该数据,但A用户因为某些原因取消了对数据的修改,数据恢复原值,此时B得到的数据就与数据库内的数据产生了不一致

不可重复读

A用户读取数据,随后B用户读出该数据并修改,此时A用户再读取数据时发现前后两次的值不一致

并发控制的主要方法是封锁,锁就是在一段时间内禁止用户做某些操作以避免产生数据不一致

这次主要讲解锁的粒度 问题

锁粒度是被封锁目标的大小,封锁粒度小则并发性高,但开销大,封锁粒度大则并发性低但开销小

SQL Server支持的锁粒度可以分为为行、页、键、键范围、索引、表或数据库获取锁

资源 描述

RID 行标识符。用于单独锁定表中的一行。

键 索引中的行锁。用于保护可串行事务中的键范围。

页 8 千字节 (KB) 的数据页或索引页。

扩展盘区 相邻的八个数据页或索引页构成的一组。

表 包括所有数据和索引在内的整个表。

DB 数据库。

 

示例:
1.    行所
CREATE TABLE temp(
A CHAR(2),
B CHAR(2),
C CHAR(2),
)

INSERT INTO temp VALUES ('a1','b1','c1')
INSERT INTO temp VALUES ('a2','b2','c2')
INSERT INTO temp VALUES ('a3','b3','c3')
--增加更新锁,持续30s
begin tran 
update temp WITH(ROWLOCK) set A='a0' where B='b1'
waitfor delay '00:00:30'
commit TRAN

SELECT * FROM temp
--必须在等待30s后才能执行更新。但对于查询没有影响
update temp WITH(ROWLOCK) set A='a0' where B='b1'
2.    锁定表
begin tran 
update temp WITH(TABLOCK) set A='a0' where B='b1'
waitfor delay '00:00:30'
commit TRAN
--此时更新表中的任何一行数据都必须等待30s。及整个表都被锁定
update temp WITH(ROWLOCK) set A='a0' where B='b2'

 

posted @ 2013-04-25 13:17  帅的纯净水  阅读(904)  评论(0编辑  收藏  举报