分类: Mysql/postgreSQL
2014-09-22 23:01:36
6.1 什么是锁
·MyISAM,其锁是表锁,性能较差
·Microsoft SQL Server 2005版本前,是页锁,2005版本后,支持乐观并发和悲观并发
乐观并发下开始支持行级锁
·InnoDB存储引擎锁实现与Oracle非常相似,提供一致性非锁定读、行级锁支持
6.2 InnoDB存储引擎中的锁
6.2.1锁类型
行级锁
·共享锁(S Lock) :允许事务读一行数据
·排他锁(X Lock) :允许事务删除或者更新一行数据
表级锁
·意向共享锁(IS Lock),事务想要获得一个表中某几行的共享锁
·意向排他锁(IX Lock),事务想要获得一个表中某几行的排他锁
(因为InnoDB存储引擎支持的是行级别锁,所以意向锁其实不会阻塞除全表扫以外的任何请求)
查看锁情况
·INNODB_TRX
·INNODB_LOCKS
·INNODB_LOCKS_WAITS
6.2.2 一致性的非锁定读操作
一致性非锁定读:指InnoDB存储引擎通过行多版本控制来读取当前执 行时间数据库中的数据。如读取的行正执行DELETE、UPDATE操作,不 会等待行上锁释放,而是读取快照数据
快照数据:指该行之前版本的数据,通过Undo段来实现,Undo用来在 事务中回滚数据,读取快照数据不需要上锁,历史数据没必要进行修改
MVCC:多版本并发控制,一行可能不止有一个快照数据。
Read Committed 总是读取被锁定行的最新一份快照数据
Repeatable Read(默认),读取事务开始时的行数据版本
6.2.3 对读取加锁
InnoDB存储引擎Select 操作默认下使用一致性非锁定读,可以使用
Select ... For update 加X锁,其他事务任何锁都被阻塞
Select ... Lock In Share Mode 对行加S锁,其他事务可以加S锁,但对于加X锁, 会被阻塞
6.2.4 自增长和锁
·AUTO-INC Locking 表锁机制,为了提高性能,锁不是在事务完成后释放,而是 自增长值插入的SQL语句执行完后立即释放。
·5.1.22版本开始,存储引擎提供一个参数innodb_autoinc_lock_mode,默认值为1, 对于知道插入行数的语句,使用互斥量;不知道行数的插入语句,使用表锁
6.2.5 外键和锁
·InnoDB存储引擎,对于一个外键列,自动加一个索引,这样可以避免表锁
·对于外键值的插入或更新,需查询父表的记录,不是使用一致性非锁定读方式, 这样会发生数据不一致的问题,使用Select ...Lock In Share Mode,主动对父表加S 锁
6.3锁算法
·Record Lock:单个行记录上的锁
·Gap Lock:间隙锁,锁定一个范围,但不包含记录本身
·Next-key Lock:Gap Lock + Record Lock, 锁定一个范围,并且锁定记录本身
1、锁住索引记录,要是没有索引,使用隐式主键来进行锁定。
6.4锁问题
6.4.1 丢失更新
经典数据库问题,例如:
(1)事务T1查询一行数据,放入本地内存,并显示给一个终端用户User1;
(2)事务T2查询一行数据,并将取得的数据给终端用户User2;
(3)User1修改这行记录,更新数据库并提交;
(4)User2修改这行记录,更新数据库并提交。
6.4.2 脏读
脏页: 缓存数据页,还没刷新到磁盘,数据不一致
脏读:一个事务读取到另一个事务还没提交的数据
6.4.3 不可重复读
一个事务内多次读同一数据,在两次读数据间,第二个事务修改了数据,导致两次 读到的数据不一样。(可以接受)
6.5 阻塞
默认情况下InnoDB不会对异常进行回滚,包括超时引发的错误异常。需要用户判断, 再进行下一步操作,是commit,还是rollback
6.6 死锁
6.7锁升级
·Microsoft SQL Server 数据库支持锁升级,因为锁是一个耗内存资源的开销
·InnoDB不存在锁升级问题,1把锁与1000把锁一样,都没有开销