日期:2014-05-16  浏览次数:20767 次

mysql事务与锁机制

mysql事务与锁的机制

我们先来谈谈mysql的锁

? ?锁:顾名思义就是对某个资源(可以是一张表,也有可能是一行或者多行记录)进行加锁操作,让自己有优先处理的权利。唉姑且就这么理解吧!

?那么mysql究竟有哪几种类锁呢?

?

  1. 共享锁
某些地方叫乐观锁,其实也是它了(东叫一下西叫一下ztm晕,能不能有个统一的叫法!!)那共享锁是怎么个意思呢?还是先举个例子说吧,假如说事务A读到一条记录,并且修改了该条记录的一个字段的值a改成了b,正在这个时候事务B也读到了这条记录并且获取的A事务修改后的字段值b(不会不知道mysqlupdate时候会对记录加锁吧),事务B想把该字段的值改为c,在此时事务A的修改操作并未提交。那对不起了事务B,因为是事务A先对该记录加锁的,你此时还没有对该条记录上锁的权限哦,不要急哦,等事务A提交之后你就可以改了。

?

好了,差不多明白共享锁了吧,有点啰嗦了,还是简单的在说下吧。
共享锁就是只针对update时候加锁,在未对update操作提交之前,其他事务只能够获取最新的记录但不能够update操作。
? ?2.排他锁
某些地方也把他叫做悲观锁,那么我来给你说下这种锁是怎么个悲剧法的哈,稍等。。。
还是一样,先来个例子展示下它的悲剧
还是用上个例子吧,事务A查到一个记录,并修改了其中的一个字段a的值为b,这个时候事务B来获取这条记录,我靠,怎么获取不到呢?原来是排他锁在作怪,这是什么情况。原来排他锁在获取记录的时候就对这条记录上了锁,而且别的事务连获取这条记录的权限都没有,更别提要修改了,必须等到事务A提交了事务释放了锁之后别的事务才能够获取到这条记录。排他锁,你也太tm小心眼了吧!!
所以,知道什么是排他锁了吧,
一句话,就是在一开始就对记录上锁了,在本事务未提交之前别的事务无权进行任何操作。我晕,我觉得该把它叫小气锁更好更贴切。
那么既然有这两种锁,你认为那种锁比较好,你会选用哪种锁呢?
呵呵,不要听我的误导哦,其实这两种锁各有利弊,不要看叫乐观锁就很乐观,叫悲观锁就很悲观哦,这个要看你项目的具体业务的。。
假如你的项目对并发很高对效率要求很高,那么你该选用乐观锁,因为在别的事务对某些记录上锁后在事务未提交之前其他事务是有权限去查看的,但是当出现意外导致事务回滚时候,其他事务会多进行一步操作,那就是重新获取这些对象了,不过这比排队等锁要好多了
假如你的项目并发数不是很多,同时对整个业务的原子操作要求很高这个时候排他锁是很不错的选择。
好了,前面我们废话了这么多,那么mysql究竟能对那些对象上锁呢?带着这个问题下一步我们就得了解下mysql的锁的级别了。
mysql锁的级别分为三类:页级锁,表级锁,行级锁。
那有三个级别的锁,mysql究竟用的是哪个级别的呢?这个还得看你用的是什么mysql的引擎了
mysql大概有下面几个数据库引擎和对应的锁级别
MyISAM引擎:使用的是表级锁
MEMORY/heap:使用的是表级锁
BDB:使用的是页级锁,不过它也支持表级锁的哦
InnoDB:使用的是行级锁,它夜支持表级锁的哦
好了,关于锁的东西我大概的是说完了,下面在聊聊mysql的事务吧
事务是什么东西,那么我们还是来简单说下吧
事务,以我的理解来说就是对数据库的一次原子性的操作。
这个原子操作包含多个数据操作语句,要是单条select语句就没有加事务的必要性了。
那么在多个事务对共享数据进行操作时就容易发生数据不一致啊等等的问题了,那么sql标准定义了如下几个名词
1、脏读(dirty?reads)
定义:一个事务读取了另一个并行事务未提交但更改过的数据。
2、不可重复读(non-repeatable reads)