Skip to content

Latest commit

 

History

History
81 lines (45 loc) · 3.76 KB

File metadata and controls

81 lines (45 loc) · 3.76 KB

Mysql事务简介

事务是指一组sql语句组成的数据库逻辑处理单元,在这组的sql操作中,要么全部执行成功,要么全部执行失败

  • 简单又经典的例子就是转账了,事务A中要进行转账,那么转出的账号要扣钱,转入的账号要加钱,这两个操作都必须同时执行成功,为了确保数据的一致性

Mysql中事务的四大特性

  • 原子性

    事务的原子性操作,对数据的修改要么全部执行成功,要么全部失败,实现事务的原子性,是基于日志的Redo/Undo机制

    • Redo/Undo机制
      • Redo log 用来记录某数据块被修改后的值,可以用来恢复未写入 data file 的已成功事务更新的数据
      • Undo log 记录数据更新前的值,保证数据更新失败能够回滚
      • 举例说明:
        • 假如某个时刻数据库崩溃,在崩溃之前有事务A和事务B在执行,事务A已经提交,而事务B还未提交。当数据库重启进行 crash-recovery 时,就会通过Redo log将已经提交事务的更改写到数据文件,而还没有提交的就通过Undo log进行roll back
  • 一致性

    执行事务前后的状态要一致,可以理解为数据一致性

  • 隔离性

    事务之间相互隔离,不受影响

    • 事务隔离级别:

      • 读未提交

        • 会读到另一个事务的未提交的数据,产生脏读问题

          • 举例说明:

            启动事务,此时数据为初始状态;更新数据,但不提交;再次读取数据,发现数据已经被修改了;这就是所谓的“脏读”

      • 读提交

        • 大多数数据库系统的默认隔离级别(但不是MySQL默认的)

        • 一个事务只能看见已经提交事务所做的改变,不可重复读,同一select可能返回不同结果(update的时候)

          • 举例说明:

            启动事务;更新数据,但不提交;再次读数据,发现数据未被修改;提交事务;再次读取数据,发现数据已发生变化

      • 可重复读

        • MySQL的默认事务隔离级别

        • 同一事务的多个实例在并发读取数据时,会看到同样的数据行

        • 当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行

        • 多版本并发控制(MVCC)来解决这个问题

          • 举例说明:

            启动事务;更新数据,但不提交;再次读数据,发现数据未被修改;提交事务;再次读取数据,发现数据依然未发生变化,虽然可以重复读了,插入一条新的数据,并提交,但是却发现读的不是最新数据,这就是所谓的“幻读”;提交本次事务,再次读取数据,发现读取正常了

      • 串行化

        • 强制事务排序,使之不可能相互冲突

        • 每个读的数据行上加上共享锁

          • 举例说明:

            启动事务,此时数据为初始状态;B此时进入了等待状态,原因是因为A的事务尚未提交,只能等待(也肯能会超时);提交事务;插入成功

  • 持久性

    事务提交后,这个事务的状态会被持久化到数据库中

Mysql的锁机制

  • 分享锁/读锁、排他锁/写锁、间隙锁、行锁、表锁
  • 读未提交是没有加任何锁
  • 串行化加的是一把大锁,读的时候加共享锁,不能写,写的时候,加的是排它锁,阻塞其它事务的写入和读取,其它的事务长时间不能写入就会直接报超时