当前位置:首页 > IT技术 > 数据库 > 正文

mysql+Mybatis底层原理
2021-09-17 16:44:54


这段时间趁着工作不忙,一起来回顾一下Mybatis+mysql的一些底层东西

 

一、mysql

 1:mysql锁有哪些?---》共享锁(读锁)和排他锁(写锁)

   1):共享锁(通过 lock in share model实现)

      共享锁又叫读锁,也就是执行一条查询sql语句的时候实现的,一旦共享锁,此时查询的数据被锁定,不能被其他事务进行写操作

   2):排它锁(写锁)

         个人对排它锁定义:排它锁就是对数据锁定,很大程度上讲数据不能被其他事务修改(个人理解,仅关参考)

         正解:排它锁又分为表级锁和行级锁,下面详细讲解这两个锁的作用:

     2.1)表级锁:一旦事务使用的是表级锁,那么整个表的数据不能被读取以及修改,一般是不会这么操作。

     2.2)行级锁:行级锁的作用就是事务开启,锁定当前读取的行数据不能被修改或者通过版本号控制修改成功或失败(个人总结,仅供参考)

         正解:行级锁又分为乐观锁,悲观锁,下面详细讲解:

     2.2.1)悲观锁(通过for update 实现):悲观锁的含义就是事务开启使用悲观锁,此时读取的行数据,不能被修改

                示范sql:select * from user where id=1 for update;

 

     2.2.2)乐观锁:乐观锁的话是允许其他事务读取或者修改,但是修改成功与否通过版本号 version 来控制

    

二:事务的隔离性和隔离级别---相信大家都知道的,但是因为需要讲解其他内容,必须引入这该死的简单东西

  隔离特性:

    原子性  -  -  要么全部失败,要么全部成功

    一致性  -  -  一般用在转账,A账户扣1000,转到B账户,B账户增加1000

   隔离性   -  -  一个事物正在处理的数据,其他事务不能看见

   持久性   -  -  数据一旦保存到数据库,那么数据永久保存

 隔离级别:

    1-读未提交

         比如两个事物A、B。事物A在读取的数据,正好是事物B正在修改但是未commit事物的用户的名字 张三-->李四,然后此时事物B出现程序错误,但是A读取的是李四来操作数据,这就是幻读(后面讲解MVCC+间隙锁来解决幻读)

 

    2-读已提交

        比如两个事物A、B。事物A在第一次读取在读取用户表id=1的数据是张三,正好此时事物B正在修改并且提交了事物(commit)commit事物的用户的名字 张三-->李四,某些情况下事物A再查询一遍是否是张三,但是事物B已经修改并且提交,此时事物A读取到的是李四,这就是两次读取的结果不一致

 

    3-可重复复读

        mysql的默认隔离级别,每次读取的结果都一样,但是会产生幻读(MVCC+间隙锁解决)

    4-串行 

       该种隔离级别一般不会使用,因为会给每一行数据都会加锁,导致大量的超时锁和锁锁竞争问题

 

三:ACID如何保证?

   A:原子性 ——数据库有undo log日志。记录需要回滚的日志信息。事务回滚时撤销已经成功执行的sql

  C:一致性——使用代码保证(一般都是用try cay语句的咯,并且方法上加上@Transtal(level=Excetion.class))

   I :隔离性 —— MVCC(详细讲解MVCC传送们)

  D:持久性 —— 内存+redo log日志。sql执行的时候,commit事务后,会通过redo log刷盘,宕机的时候,可以通过redo log恢复。

 

四:MVCC是什么?如何解决幻读

 

 

九:mybatis 的编译原理以及执行原理

     1、编译原理:看下图,整体流程就不用文字描述,相信大伙能看懂!

        mysql+Mybatis底层原理_sql语句

  2:执行原理--照样看图比较直观(大致流程大伙应该能看得懂,要是还看不懂,那就gg了)

mysql+Mybatis底层原理_数据_02

 

 

 

十、mybatis的组成结构图

mysql+Mybatis底层原理_数据_03

 

十一、 mybatis的exectory执行器有哪些,有哪些区别?

  我们能看到第十点的mybatis总结架构图,第二组成部分的 SQL执行,里面包含3种执行器:下面详细说:

 SimpleExectory执行器:执行select和update的sql语句,每次执行sql,都会创建Statement对象,用完就关闭

 

 RuseExectory执行器:执行select和update的sql语句,它的区别在于使用执行的sql作为key,在Map<String,Statement>做缓存,如果没有,则创建Statement对象,并且缓存到Map<String,Statement>里面,用完不关闭Statement对象

 

 BatchExectory执行器:只执行update语句(JDBC不支持批量查询),将sql添加到 addBatch()中,等待统一执行 exectoryBatch()。它缓存了多个Statement对象

 

十二、mybatis为啥要预编译处理?

我们首先了解预编译处理的好处:JDBC使用PrestateStatement 来抽象预编译sql语句,预编译后可以优化sql语句,并且一般都能够直接执行,所以DBMS(mysql、SQL或其他数据库不需要再进行预编译处理),并且预编译的语句对象可重复利用,即 PrepareStatement 对象缓存下载

 


 



 


 


 


本文摘自 :https://blog.51cto.com/u

开通会员,享受整站包年服务立即开通 >