Mysql基础3(事务,锁,mvcc)

文章最前: 我是Octopus,这个名字来源于我的中文名--章鱼;我热爱编程、热爱算法、热爱开源。所有源码在我的个人github ;这博客是记录我学习的点点滴滴,如果您对 Python、Java、AI、算法有兴趣,可以关注我的动态,一起学习,共同进步。

相关文章:

  1. Mysql基础1(索引)
  2. Mysql基础2(引擎,体系结构,查询机制))
  3. Mysql基础3(事务,锁,mvcc)
  4. Mysql基础4(深入理解mvcc)

文章目录:

1.事务

2. 锁


InnoDB的特性:

                    


1.事务

   什么是事务?

         事务是数据库的最小执行单位,是单个逻辑工作单元执行的一系列操作,事务是一组不可分割的操作组合。

  典型的事务场景:

        update user_account set balance =balance-1000 where userID=3;

        update user_account set balance= balance+1000 where userID=1;

        begin/start transaction   ---手工

        commit/rollback             ----事务提交或回滚

        set session autocommit =on/off;    ----设定事务是否自动开启

        JDBC编程:

                          connection.setAutoCommit(boolean);

        Spring 事务aop编程:

                          expression=execution(*);

        事务的ACID特性:

         原子性:要么一起执行成功,要么全部失败进行回滚

         一致性:数据状态的改变是一致性的,a-100;b+100;a+b的综合不变

         隔离性:事务和事务之间是相互没有影响

         持久性:事务提交了就会永远保持,就算数据库宕机,重启之后也会继续执行      


1.脏读

                      

       2.幻读:

                                 

    3.重复读

                                   


事务的四种隔离级别:

   1) Read uncommitted(读未提交) -未解决并发问题

          事务未提交对其他事务是可见的;

   2)  Read committed(读已提交) ----解决脏读问题

           一个事务开始之后,智能看到自己提交的事务所做的修改,不可重复读;

   3)  Repeatable Read(可重复读)----解决不可重复读问题

            在同一个事务中多次读取同样的数据结果是一样的,这种隔离级别未定义解决幻读的问题;

   4)  Serializable(可串行化)---解决所有问题

            最高的隔离级别,通过强制事务的串行执行;

            InnoDB引擎对隔离级别的支持程度:

                           


2. 

     锁是用于管理不同事务对共享资源的并发访问

     表锁与行锁的区别:

              锁定粒度:表锁>行锁

              加锁效率:表锁>行锁

              冲突概率:表锁>行锁

             并发性能:表锁<行锁

     Innodb存储引擎支持行锁和表锁(另类的行锁)

     Mysql InnoDB锁类型:

      1.共享锁(行锁)

      2.排它锁(行锁)

      3.意向锁共享锁(表锁)

      4.意向锁排它锁(表锁)

      5.自增锁

     行锁的算法:

      1.记录锁

      2.间隙锁

      3.临键锁

      共享锁:又称为读锁,就是多个事物对于同一数据可以共享一把锁,都能访问到数据,但是只能读不能修改;

      加锁解锁方式:select * form users where id=1 lock in share mode;

                                commit/rollback

       排它锁:有称为写锁,排它锁不能与其他说并存。

        加锁释放锁方式:

                 delete/update/insert 默认加上x锁

                 select * form table_name where .... for update 

                commit/rollback

               行锁到底锁住了什么?

                     InnoDB的行锁是通过给索引上的索引项加锁来实现的。

                     只有通过索引条件进行数据检索,InnoDB才能使用行级锁,否则InnoDB将使用表锁(锁住索引的所有记录)

                     表锁:Lock tables xx read/write;

                    意向锁共享锁&意向锁排它锁:

                    意向共享锁(IS):表示事务准备给数据行加入共享锁,即一个数据行共享锁必须先取得该表的IS锁,意向共享锁之间可以相互兼容。

                    意向排它锁(IX):表示事务准备给数据行加入排它锁,即一个数据行排它锁前必须先取得该表的IX锁,意向排它锁之间是相互兼容的。

                   意向锁(IS,IX)是InnoDB数据操作之前自动加的,不需要用户干预。

                   意义: 当事务想去进行锁表时,可以先判断意向锁是否存在,存在时则可快速返回该表不能启用表锁;

                   自增锁:

                    针对自增列自增长的一个特殊的表级别锁

                    show variables like 'innodb_autoinc_lock_mode';

                    默认取值1,代表连续,事务未提交ID永久丢失

                   记录锁&间隙锁&临键锁

                    临键锁:锁住记录+区间(左开右闭)

                    当sql执行按照索引进行数据的检索时,查询条件为范围查找(between,and)等并有数据命中,则此时sql语句加上的锁为next-key locks,锁住索引的记录+区间(左开右闭)

                  间隙锁:锁住数据不存在的区间

                  记录锁:锁住具体的索引项,查询条件等匹配且查询的数据是存在。唯一索引,条件为精准匹配,退化为记录锁

                  临键锁:Innodb默认的行锁算法,当数据不存在临键锁退化为间隙锁,间隙锁只在可重复读事务隔离级别存在;

                 利用锁怎么解决脏读(在锁上加排它锁):

                             

                 利用锁解决不可重复读问题(数据行加上共享锁):

                             

        怎么解决幻读问题?(加上临键锁)

                                   

       


死锁的介绍:

             1.多并发事务

             2.没个事务都要持有锁

             3.每个事务都要继续持有锁

             4.事务之间产生加锁的循环等待,形成死锁      


避免死锁:

              1.类似的业务逻辑以固定的顺序访问表和行;

              2.大事务拆小,大事务更倾向于死锁,如果业务允许,将大事务拆小

              3.在同一个事务中,尽可能做到一次锁定所需要的所有资源,减少死锁的概率。

              4.降低隔离级别,如果业务允许,将隔离级别调低也是较好的选择

              5.为表添加合理的索引,可以看到如果不走索引将会为表的每一行记录添加锁。     


查看mysql的设置的事务隔离级别

              select global .@@tx_isolation;      select @@tx_isolation;
              tx1: set session autocommit=off;
              update users set lastUpdate=now() where id =1;
              在未做commit/rollback操作之前
              在其他的事务我们能不能进行对应数据的查询(特别是加上了X锁的数据)
              tx2: select * from users where id > 1;
              select * from users where id = 1;

     ex2:
              tx1: begin
              select * from users where id =1 ;
              tx2: begin
              update users set lastUpdate=now() where id =1;
     tx1:
              select * from users where id =1;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值