天天看点

数据库锁原理

1 为什么需要锁

数据库通常有大量的用户在同时操作,所以并发的情况下需要控制对临界资源的操作,数据库通过锁来控制对临界资源的访问,从而保证数据的一致性。例如对于同一个账户,操作之前账户余额为1000,同时开始2个事务,一个事务取款100,一个事务往账户中汇入100,那么2个事务结束后,账户的余额必须还是1000,否则要么银行不干,要么个人不干。

2 锁类型

2.1 共享锁(读锁)

读锁是共享的,互相不阻塞,也就是可以多个客户同时读取同一资源,而不互相干扰。

加锁条件:当执行select时,数据库为这个事务分配一把共享锁,来锁定被查询的数据。

解锁条件:默认情况下,数据被读取之后,数据库立即解锁。例如select * from table中,先锁定第一行,读取后,立即解锁第一行,然后再锁定第二行,这样大大降低锁争用程度。在repeatable read和serializable 这两种事务隔离级别下,共享锁是在事务结束时释放的,serializable对表加锁。

2.2 排它锁(独占锁)(写锁)

写锁是排他的,一个写锁会阻塞其他的读锁和写锁,只有这样才能保证同一时刻,只有一个用户能够写入,并阻止其他用户读取正在写入的同一资源。如果要锁定的数据资源,已经放置了其他的锁,则不能再放置排它锁。

加锁条件:当执行insert update 和delete语句时,数据库会对操纵的资源使用排它锁。

解锁条件:事务结束时解锁。

3.锁原理

锁的基本原理如下:

1.当第一个事务访问数据库资源时,如果执行select语句,则必须先获得共享锁,如果执行insert update和delete时,必须获得排它锁

2.当第二个事务也要访问相同的资源时,如果执行select语句,也必须先获得共享锁,如果执行insert update或者delete,也必须获得共享锁。根据已经放置在资源上的锁类型,来决定第二个事务是应该等待第一个事务释放锁,还是立即获得锁。

[img]http://dl2.iteye.com/upload/attachment/0104/2212/53d4fe20-4751-337f-ac03-0568295faec1.gif[/img]

4 锁粒度

常见的锁有表锁、 行锁、 页锁、外键锁等。

锁有一定的消耗,主要有:获得锁,检查锁是否已经解除,释放锁等,这些操作都会增加系统的开销。

表锁开销比较小,但是并发性能也较差,行锁并发性能高,但是需要更多锁,数据库系统一般都支持锁的自动升级,例如一个事务中的锁过多的时候,可能会将行锁升级到表锁。

mysql的各个存储引擎根据不同的应用场景采用不同的锁机制,MyISAM存储引擎采用表锁,InnoDB使用行锁。如果执行alert table之类的操作,服务器也会采用表锁,而忽略存储引擎的锁机制。

页锁,某些数据库支持页锁,页锁粒度介于行锁和表锁之间,用于锁定存放数据的页,1页通常含有n个数据行。

外键锁:外键会产生高级别的锁,后面介绍死锁的时候会提到。

5.乐观锁和悲观锁

悲观锁:假设如果不加锁就一定会出现问题。

乐观锁:先假定不会出现并发问题,出现问题后再采取相应的措施。

悲观锁通过select * from tbl for update实现。

乐观锁可以在表中加一个version字段,每次更新的时候都+1,这样如果出现并发,第二次更新的时候version的值已经不再匹配,可以在这时采取相应的措施。

6 死锁

6.1 死锁是如何产生的

同java的死锁一样,都是互相等待对方释放锁,造成了相互阻塞,造成的死锁。

请看下面的表格:

[img]http://dl2.iteye.com/upload/attachment/0104/2214/6bd33583-1a0d-36b8-8910-f19cfb0cfbd6.gif[/img]

6.2 如何避免死锁

1.修改操作表的顺序

从上面的示例中可以看出,如果调整一下操作表的顺序就可以避免死锁。

2.外键

如果向子表写记录,那么外键约束会检查父表的记录,并锁住父表的记录,来保证这条记录不会在这个事务完成之时就被删除了。

产生高级别的锁,会阻止其他事务操作或者其他DML操作,如果是因为外键产生的死锁,可以去掉外键约束,由应用来保证数据的完整性,通常生产环境都不建议加外键约束。

3.短事务

缩短事务的执行时间,可以减少锁的持有时间,可以降低死锁的风险。

7 锁可能出现的问题

上锁是有开销的,即使不是给数据行而是给数据页上锁,也是有一定的时间的,如果第一个事务update一张大表,这时候第二个事务update这张大表比较靠后的位置的数据,这时候就可能会出现,第一个事务还没来得及给相应的数据上锁,第二个事务已经上了锁,所以出现第一个事务要等待第二个事务提交后释放锁,才能继续执行的情况。

8 参考资料

http://www.iteye.com/topic/743285

http://www.iteye.com/topic/236271

http://www.iteye.com/topic/170393

http://thrillerzw.iteye.com/blog/1880242

http://cfeers.iteye.com/blog/760992 *

http://blog.sina.com.cn/s/blog_548bd2090100ir7k.html

http://www.cnblogs.com/ggjucheng/archive/2012/11/14/2770445.html

http://blog.163.com/[email protected]/blog/static/33376057200851625011100/

http://wenku.baidu.com/link?url=kS0uwo_ykqH5PJg7AM39Mf2jrZfOqn7gusgJkf8s2kJShOr-n_9CiykvDqzEIoHxYkokG_XY7keyu6OL-Bn_R4pw3xW1pN0IUNbYxNrdu3q

《Java特种兵》