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