MySQL-什么是事务? 事务的隔离级别有哪些? 什么是脏读、不可重复读、幻读?

什么是事务?

一个事务就是一个完整的、最小的业务逻辑。

假设一个转账需求,A 向 B 转账 100 元,那么:
1. 将 A 账户的钱 - 100 元(update语句)
2. 将 B 账户的钱 + 100 元(update语句)
这就是一个完整的业务逻辑。

以上的操作是一个最小的工作单元,两条update语句必须要求要么同时成功,要么同时失败,才能保证钱的正确。

只有DML语句才会有事务这一说,其它语句和事务无关。

事务其实就是多条DML语句 同时成功 或者 同时失败。

事务是怎么做到多条DML语句同时成功和同时失败的呢?

mysql默认的InnoDB存储引擎支持事务:提供一组用来记录事务性活动的日志文件。
在事务执行的过程中,每一条DML的操作都会记录到 “事务性活动的日志文件” 中。

在事务的执行过程中,我们可以提交事务(commit),也可以回滚事务(rollback)。
提交事务: 清空事务性活动的日志文件,将数据全部彻底持久化到数据库表中。提交事务标志着事务的结束。并且是一种全部成功的结束。
回滚事务:将之前所有的DML操作全部撤销,并且清空事务性活动的日志文件。回滚事务标志着事务的结束。并且是一种全部失败的结束。

在mysql如何开启事务、提交事务、回滚事务?

首先,在MySQL中默认自动提交事务,也就是:每执行一条DML语句,则提交一次!

这种自动提交实际上是不符合我们的开发习惯,因为一个业务通常是需要多条DML语句共同执行才能完成的,为了保证数据的安全,必须要求同时成功之后再提交,所以不能执行一条就提交一条。

演示事务:
start transaction;  # 开启事务

insert into t_user (name, age) values ('a', 18);

insert into t_user (name, age) values ('b', 19);

commit; # 提交事务, 也可以执行 rollback; 回滚事务

事务有什么特性?

A: 原子性
    事务是最小的工作单元。不可再分。
C:一致性
    所有事务要求,在同一个事务当中,所有操作必须同时成功,或者同时失败,以保证数据的一致性。
I:隔离性
   一个事务内部的操作和使用的数据对并发的其他事务是隔离的。
D:持久性
    一个事务提交后,数据库中数据的更改是永久性的,其他的操作或错误不会对其产生影响。

关于事务隔离性?

事务有 4 个隔离级别:
读未提交(read uncommitted)、
读已提交(read committed)、
可重复读(repeatable read)、
串行化(serializable),
隔离等级依次增加
  • 读未提交(read uncommitted)

    什么是 读未提交?
      事务A 可以读取到 事务B 未提交的数据
    
    这种隔离级别存在什么问题?
      脏读现象(Dirty Read) 
    
    这种隔离级别一般都是理论上的,大多数的数据库隔离级别都是 读已提交 级别起步!   
    
  • 读已提交(read committed)

    什么是 读已提交?
      事务A 只能读取到 事务B 已提交的数据
    
    这种隔离级别存在什么问题?
      解决了 脏读现象,
      但是存在 不可重复读
      即不可重复读取数据,事务A 开启之后,第一次读到的数据是3条,当前事务还没有结束,可能第二次再读的时候,读到的数据是4条,3不等于4,称为不可重复读取。
    
    oracle数据库默认的隔离级别 
    
  • 可重复读(repeatable read)

    什么是 可重复读?
      事务A开启之后,不管是多久,只要事务A 没有结束,每一次在事务A中读取到的数据都是一致的。即使事务B 将数据已经修改,并且提交了,事务A 读取到的数据还是没有发生改变,这就是可重复读。
    
    这种隔离级别存在什么问题?
      解决了 不可重复读现象,
      但是存在 幻读
      每一次读取到的数据可能(其他事务可能对这个数据有操作)都是幻象。不够真实!
    
    mysql中默认的事务隔离级别  
    
  • 串行化(serializable)

    什么是 串行化?
      这是最高隔离级别,这种隔离级别表示事务排队,不能并发!
    这种隔离级别存在什么问题?
      解决了所有的问题。每一次读取到的数据都是最真实的,但是效率是最低的。
    

对MySQL隔离级别进行操作?


select @@tx_isolation;   # 查看隔离级别

set global transaction isolation level read uncommitted;    # 设置隔离级别为 读未提交

posted @ 2021-03-27 15:35  等你下课啊  阅读(156)  评论(0)    收藏  举报