MySQLInnoDB存储引擎之锁(二)

2015-01-23 22:07:59 · 作者: · 浏览: 12
y2df3vNPL+NLUsaPWpMr9vt3C37yttcTSu9bC0NSho0lubm9EQrTmtKLS/cfmttTT2nNlbGVjdNPvvuTWp7PWwb3W1tK71sLQ1LXEy/i2qLbBstnX9zo8YnI+CiAgICAgICAgICAgIHNlbGVjdCAuLi4gZm9yIHVwZGF0ZaO6ttS2wcihtcTQ0LzHwry801jL+KOsxuTL+8rCzu+yu8TcttS4w9DQvNPIzrrOy/ihozxicj4KICAgICAgICAgICAgc2VsZWN0IC4uLiBsb2NrIGluIHNoYXJlIG1vZGWjurbUtsHIobXE0NC8x8K8vNNTy/ijrMbky/vKws7vv8nS1LbUuMPQ0LzTU8v4o6y1q8rHyOe5+7zTWMv4o6zU8rvhsbvX6Mj7oaM8YnI+CiAgICDX1NT2s6TT68v4PGJyPgogICAgICAgINTaSW5ub0RCtOa0otL9x+a1xMTatOa94bm51tCjrLbUw7+49rqs09DX1NT2s6QmIzIwNTQwO7XEse22vNPQ0ru49tfU1PazpLzGyv3G9yhhdXRvLWluY3JlbWVudCBjb3VudGVyKaGjtbG21Lqs09DX1NT2s6S1xLzGyv3G97XEse29+NDQsuXI67LZ1/fKx6Os1eK49rzGyv3G97vhsbuz9cq8u6+jrNa00NDI58/CtcTT777kwLS1w7W9vMbK/cb3tcQmIzIwNTQwOzpzZWxlY3QgbWF4KGF1dG9faW5jX2NvbCkgZnJvbSB0IGZvciB1cGRhdGWho7LlyOuy2df3u+HSwL7d1eK49tfU1PazpLXEvMbK/cb3JiMyMDU0MDu80zG4s9Po19TU9rOkwdCho9XiuPbKtc/Wt73KvbPGzqpBVVRPLUlOQyBMb2NraW5no6zV4srH0rvW1szYyuK1xLHty/i7+tbGo6zOqsHLzOG437LlyOu1xNDUxNyjrMv4srvKx9Ta0ru49srCzvHN6rPJ1q6687LFys23xaOstvjKx9TazeqzybbU19TU9rOkJiMyMDU0MDuy5cjrtcRTUUzT777kuvO74cGivLTKzbfFoaNBVVRPLUlOQwogTG9ja2luZ9Ta0ru2qLPMtsjJz8zhuN/By7Kit6Ky5cjrtcTQp8LKo6y1q8rHu7m05tTa0rvQqdDUxNzJz7XEzsrM4qGjytfPyKOsttTT2tPQ19TU9rOkJiMyMDU0MDu1xMHQtcSyoreisuXI69DUxNy9z7Luo6zKws7xsdjQ67XItP3HsNK7uPay5cjrtcTN6rPJKLK708O1yLT9ysLO8bXEzeqzySmho8bktM6jrLbU09ppbnNlcnQgLi4uIHNlbGVjdLXEtPPK/b7dwb+1xLLlyOu74dOwz+yy5cjrtcTQ1MTco6zS8s6qwe3Su7j2ysLO8dbQtcSy5cjru+Gxu9foyPuho7TTTXlTUUw1LjEuMjKw5rG+v6rKvKOsSW5ub0RCtOa0otL9x+bM4bmpwcvSu9bWx+HBv7y2u6Wz4sG/tcTX1NT2s6TKtc/Wu/rWxqOs1eLW1rv61sa087TzzOG438HL19TU9rOkJiMyMDU0MDuy5cjrtcTQ1MTcoaPNqLn9ss7K/Wlubm9kYl9hdXRvaW5jX2xvY2tfbW9kZcC0v9jWxtfU1PazpLXExKPKvSjErMjPzqoxKaGj19TU9rOktcSy5cjrvfjQ0LfWwODI5828OjxpbWcgc3JjPQ=="https://www.cppentry.com/upload_files/article/57/1_f80zn__.jpg" alt="\">
innodb_autoinc_lock_mode的参数值及其对自增长的影响如下图: \
MyISAM存储引擎是表锁,自增长不用考虑并发插入的问题。需要注意的是:在InnoDB存储引擎中,自增长值的列必须是索引,同时必须是索引的第一个列,如果不是第一个列,MySQL是会抛出异常的。异常如图 \
外键与锁
外键主要用于完整性的约束检查。在InnoDB存储引擎中,对于一个外键列,如果没有显式地对这个列加索引,InnoDB存储引擎会自动对其加一个索引,避免表锁。对于外键值的插入或者更新,首先需要查询父表中的记录,对于父表的select操作,不是使用的一致性非锁定读的方式,因为这样会发生数据不一致的问题,所以这时使用的是select ... lock in share mode方式,即主动给父表加一个S锁。
锁的问题
dirty read 脏读
脏读就是读取到脏数据(未提交的数据)。一个事务(A)读取到另一个事务(B)中修改后但尚未提交的数据,并在这个数据的基础上操作。这时,如果B事务回滚,那么A事务读到的数据是无效的。不符合一致性。如图 \
首先事务的隔离级别有默认的RR改为RU,由上述例子可以看出会话B中两次select操作取得了不同的结果,并且这2条记录是会话A中并未提交的数据,这就产生了脏读。由此可以得出结论:脏读发生的条件是事务的隔离级别为RU。
unrepeatable read 不可重复读
事务(A)读取到了另一个事务(B)已经提交的更改数据,不符合隔离性。不可重复读和脏读的区别是:脏读是读到未提交的数据,而不可重复读则读到的是已经提交的数据。首先将事务隔离级别调整为RC,然后操作下边的例子: \
phantom read 幻读
事务(A)读取到了另一个事务(B)提交的新增数据,不符合隔离性。
锁的范围(锁的算法):
1.Record Lock :单个记录上的锁,总是会去锁住索引记录,如果InnoDB存储引擎表在建立的时候没有设置任何一个索引,那么这时InnoDB存储引擎会使用隐式的主键来进行锁定。
2.Gap Lock:间隙锁,锁定一个范围,但不包含记录本身。
3.Next-key Lock: 锁定一个范围和本身 Record Lock + Gap Lock,防止幻读。
主键索引和唯一辅助索引 = record lock
非唯一辅助索引 = next-key lock
阻塞
不同锁之间的兼容性关系,在有些时刻一个事务中的锁需要等待另外一个事务中的锁释放它所占用的资源,这就是阻塞。阻塞并不是一件坏事,其是为了确保事务可以并发且正常地运行。在InnoDB存储引擎中,参数innodb_lock_wait_timeout用来动态的控制等待的时间(默认50秒),innodb_rollback_on_timeout用来静态的设定释放在等待超时时对进行的事务进行回滚操作(默认OFF,代表不回滚)。
死锁

死锁是指两个或者两个以上的事务在执行过程中,因争