MYSQL事务隔离

介绍会出现的问题、读写锁、隔离级别

Posted by TenzT on August 20, 2018

多个事务操作同一资源会出现的问题

  • 更新丢失:A事务对数据的更新被B事务对事务的更新覆盖
  • 脏读:一个事务处理过程中读取了另一个未提交的事务中的数据。比如A向B转账100,如果不加锁,A还没提交B就读到了转入100,这时A回滚,那B只能空欢喜一场。
  • 不可重复读:一个事务内多次读取同一数据,由于中间被另一事务修改过,导致前后不一致。比如学生A查看自己成绩为100分,这时老师B在背后把该成绩改成50分,A第二天再查成绩发现不是number one 了。
  • 幻读:第一个事务对一个表中的数据进行修改,而数据设计表中的全部数据行,这时第二个事务新增/删除一条数据,那操作第一个事务的用户发现表中还有没被修改的数据行。比如小明第一次查排名发现自己是倒数第一,刚好成绩更差的小强插班进来,小明第二次查排名时开心地发现自己不是最后一名。

读写锁

  • 有两种锁:
    • 排它锁即写锁,X
    • 共享锁即读锁,S
    • 规则:上读锁时,新的事务可以继续加读锁,但绝不允许加写锁;任意一个加写锁后,不允许其他事务加任何锁。
  • 意向锁:有行级锁和表级锁,前者粒度细 IX/IS都是表锁,X/S时行锁
    • 规则:
      1. 一个事务在某个数据行对象的S锁之前,必须先获得表的IS锁或者更强的锁
      2. 一个事务在获得某个数据行对象的X锁之前,必须先获得表的IX锁
        • 解释:IX/IS之间都是兼容的,他们只是表示想加锁,二不是真正加锁

隔离级别及其实现

  • 读未提交:能解决丢失更新问题。读数据时不加锁,写数据时加行级共享锁,提交时释放锁。
  • 读提交:能解决脏读问题。事务读取数据时加行级共享锁,读完释放,保证读的时候不被修改。
  • 可重复读(MySQL默认):解决不可重复读的问题。读时加行级共享锁,直到事务结束;更新时加行级排它锁,知道事务结束才释放。InnoDB通过MVCC实现。
  • 串行化:解决幻读。读时加表级共享锁直到事务结束。写时加表级排它锁直到事务结束。

参考资料

  • 《操作系统》——北大陈向群
  • <a href=https://blog.csdn.net/u014634576/article/details/52600826>银行家算法Java实现</a>