mysql怎么模拟表锁 mysql表锁了怎么解锁( 六 )


为了解决“隔离”与“并发”的矛盾,ISO/ANSI SQL92定义了4个事务隔离级别,每个级别的隔离程度不同,允许出现的副作用也不同,应用可以根据自己业务逻辑要求,通过选择不同的隔离级别来平衡"隔离"与"并发"的矛盾
事务4种隔离级别比较
隔离级别/读数据一致性及允许的并发副作用读数据一致性脏读不可重复读幻读
未提交读(Read uncommitted)
最低级别 , 只能保证不读取物理上损坏的数据是是是
已提交度(Read committed)语句级否是是
可重复读(Repeatable read)事务级否否是
可序列化(Serializable)最高级别 , 事务级否否否
最后要说明的是:各具体数据库并不一定完全实现了上述4个隔离级别,例如 , Oracle只提供Read committed和Serializable两个标准级别,另外还自己定义的Read only隔离级别:SQL Server除支持上述ISO/ANSI SQL92定义的4个级别外,还支持一个叫做"快照"的隔离级别,但严格来说它是一个用MVCC实现的Serializable隔离级别 。MySQL支持全部4个隔离级别 , 但在具体实现时 , 有一些特点,比如在一些隔离级下是采用MVCC一致性读 , 但某些情况又不是 。
获取InonoD行锁争用情况
可以通过检查InnoDB_row_lock状态变量来分析系统上的行锁的争夺情况:
如果发现争用比较严重,如Innodb_row_lock_waits和Innodb_row_lock_time_avg的值比较高 , 还可以通过设置InnoDB Monitors来进一步观察发生锁冲突的表、数据行等,并分析锁争用的原因 。
InnoDB的行锁模式及加锁方法
InnoDB实现了以下两种类型的行锁 。
共享锁(s):允许一个事务去读一行,阻止其他事务获得相同数据集的排他锁 。
排他锁(X):允许获取排他锁的事务更新数据,阻止其他事务取得相同的数据集共享读锁和排他写锁 。
另外 , 为了允许行锁和表锁共存,实现多粒度锁机制,InnoDB还有两种内部使用的意向锁(Intention Locks) , 这两种意向锁都是表锁 。
意向共享锁(IS):事务打算给数据行共享锁,事务在给一个数据行加共享锁前必须先取得该表的IS锁 。
意向排他锁(IX):事务打算给数据行加排他锁,事务在给一个数据行加排他锁前必须先取得该表的IX锁 。
InnoDB行锁模式兼容性列表
如果一个事务请求的锁模式与当前的锁兼容,InnoDB就请求的锁授予该事务;反之,如果两者两者不兼容,该事务就要等待锁释放 。
意向锁是InnoDB自动加的 , 不需用户干预 。对于UPDATE、DELETE和INSERT语句,InnoDB会自动给涉及及数据集加排他锁(X);对于普通SELECT语句,InnoDB会自动给涉及数据集加排他锁(X);对于普通SELECT语句,InnoDB不会任何锁;事务可以通过以下语句显示给记录集加共享锁或排锁 。
共享锁(S):SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE
排他锁(X):SELECT * FROM table_name WHERE ... FOR UPDATE
用SELECT .. IN SHARE MODE获得共享锁,主要用在需要数据依存关系时确认某行记录是否存在 , 并确保没有人对这个记录进行UPDATE或者DELETE操作 。但是如果当前事务也需要对该记录进行更新操作,则很有可能造成死锁 , 对于锁定行记录后需要进行更新操作的应用,应该使用SELECT ... FOR UPDATE方式获取排他锁 。
InnoDB行锁实现方式
InnoDB行锁是通过索引上的索引项来实现的,这一点MySQL与Oracle不同,后者是通过在数据中对相应数据行加锁来实现的 。InnoDB这种行锁实现特点意味者:只有通过索引条件检索数据,InnoDB才会使用行级锁,否则,InnoDB将使用表锁!

推荐阅读