深入理解MySql锁与事务隔离级别

锁定义

  锁是计算机协调多个进程或线程并发访问某一资源的机制。

  数据库中,除了传统的计算资源(cpu、ram、i/o等)的争用以外,数据也是一种需要用户共享的资源。保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题。

锁分类

  从性能上分为:乐观锁和悲观锁

  (乐观锁:用版本对比来实现,数据库可设置一个版本控制的字段,每次查询时记录当时版本号,更新时与原来的版本记录对比,如果相同则进行更新操作)

  

  悲观锁:

    从数据库的操作类型区分:读锁和写锁

      读锁(共享锁):多个线程的读操作可以同时对同一数据进行

      写锁(排它锁):当前写操作过程中,其他线程的读、写操作均不可进行

    从数据的操作粒度区分:表锁和行锁

 

  表锁

    表锁的操作

      增加表锁:lock table 表名 read(write), 表名2 read(write)

      查看表上面加的锁:show open tables

      删除表锁:unlock tables

  行锁

    支持事务

      事务属性(ACID)

       原子性:一个事务方法块作为一个最小单位不可切分,对数据库的操作要不全部执行,要不全部不执行

       一致性:事务方法块对数据库的执行结果要保持一致,要不一起成功要不一起失败(倾向于执行结果)

       隔离性:每个事务对数据库的操作独立运行,不能受到其他事务的干扰

       持久性:操作后的数据库数据是永久性的

      并发事务带来的问题

       更新丢失:多个事务同时操作同一条数据,最后commit的事务的结果数据会覆盖之前事务的操作结果,造成其他事务更新数据丢失的现象

       脏读:一个事务读取某一条数据时,另外一个事务同时对此数据进行了修改却并未提交事务,而被当前事务读取到

       不可重复度:一个事务多次读取某一条数据的过程中,另外一个事务对此数据进行了修改且提交了事务,从而造成当前事务前后不同时间段从此数据中读取到了不同的值

       幻读:一个事务的多次查询过程中,另外一个数据新插入了一条数据并提交了事务,从而被当前事务所读取到

      事务隔离级别

       读未提交(read uncommitted):读取同一条数据时,可以读取到其他事务的修改操作且未commit的结果

       读已提交(read committed):读取同一条数据时,可以读取到其他事务的修改操作且已经commit的结果

       可重复读(repeatable read):某一session事务的业务过程中如果需要多次查询某一条数据,如果其他事务对此数据进行了修改且comiit,当前事务读取到的数据仍然与最初的查询结果保持不变(mysql默认的事务隔离级别)

       可串行化(serializable):多个事务同时操作同一条数据时,将多个事务串成一串,一个一个的执行(单线程,效率低)

 

  

   MVCC机制 (个人理解)

      mysql对表中的每条数据新增了两个隐藏标记:新建事务id和删除事务id,

      每个事务对某一条数据进行修改操作时,mysql类似的根据原数据clone一条数据,并设置新数据的新建事务id为当前事务的id

      每个事务对某一条数据进行删除操作时,mysql会设置目标数据的删除事务id为当前事务id,

      也就是说:某一事务对数据的修改、删除操作,mysql其实并未真实立刻进行修改或删除,而是根据当前事务id做了一个绑定,然后再根据当前事务id查询出“修改、删除”操作后的数据结果,从而模拟出当前事务的 修改、删除操作

 

      每个session事务对数据库进行查询时(首次查询),mysql会生成一个针对此session事务的快照,当此事务对数据进行修改、删除操作时会依据以上规则(类似以上操作)进行操作,然后再次生成新的快照,供此session事务之后                的查询使用

      mysql的begin/start transaction命令并不是一个事务的起点,执行到命令之后的第一个操作innoDB表的语句时,事务才会真正启动

 

    间隙锁

      某个事务对表种 4-20的数据进行修改、删除操作过程中,会在此区间产生间隙锁,当前事务结束之前其他事务不可对此间隙的数据进行修改、删除操作。(间隙锁可有效避免脏读、幻读)

 

   mysql锁的优化方法:

      尽量减小"间隙锁"的范围,从而达到更高的并发效果

      尽量控制事务大小,减少锁的占用时间

      无索引数据的话,行锁会自动升级为表锁,so:合理设计索引

      

posted on 2019-08-26 21:46  只为一人321  阅读(977)  评论(0编辑  收藏  举报

导航