MySQL 事务(面试必考!!!)

前言

  • 一个事务通常对应着一个完整的业务,同时事务是不可再分的,是最小的工作单元
  • 一个完整的业务需要批量的DML(insert,delete,update)语句共同联合完成
  • 事务只和DML语句有关,或者说DML语句才有事务。这个和业务逻辑有关,业务逻辑不同,DML语句的个数不同。

实操

接下来通过实操了解一下什么是事务:

看一个转账业务,现在有张三李四二人都揣着100块钱。

我们利用两条update修改语句将张三的钱含泪转给李四。

注意:以上两条DML语句必须同时成功或者同时失败。这也是事务不可再分的含义,其中若有一个成功或者失败则相当于把它俩拆开来看,这是不对的。

区别于非事务提交即非事务提交无法保证业务同时成功或失败

如下:sql语句会执行第一条修改语句而第二条会报错

和事务相关的术语:

  • 开启事务:start transaction
  • 事务提交:commit transaction 
  • 事务回滚:rollback transaction
  • 事务结束:end transaction

事务提交

start transaction;#开启事务

......sql语句......

commit;#事务提交

mysql如何实现事务

1.开启事务

2.事务提交/事务回滚

3.事务结束

什么是事务回滚?

即事务执行rollback语句回滚到原来的状态

注意:事务提交后进行回滚是不生效的,因为事务提交后事务的持久性就会起作用

例:对t_act进行提交和回滚操作

(1)提交操作(非事务成功)

(2)提交操作(非事务失败)

(3).提交操作(事务成功)

  • start transaction #开始事务
  • DML语句
  • commit #事务提交

(4)提交操作(事务失败)

(5)回滚操作(事务失败)

事务在执行rollback语句回滚到原来的状态!

事务的四大特性(一定要理解!!!)

1.事务具有原子性:指一个事物是一个不可分割的工作单位,其中的操作要么都成功,要么都失败。(上文提到)

2.事务具有持久性:指事务一旦提交,他对数据库的改变就应该是永久性的,接下来的其他操作或故障不应该对其有任何影响。(就是张三给李四转账转了100块,张三想再拿回去已经不可能了(除非进行其他业务))

  持久性问题的产生:

       背景:Mysql为了保证存储效率,每次读写文件都是先对缓存池(BufferPool)操作缓冲池再定期刷新到磁盘中(这一过程称为刷脏)。

       产生:由于数据不是直接写到磁盘,那么如果主机断电,就会有一部分数据丢失。

       解决:通过重做日志(redo 1og)恢复数据。在每次修改数据之前,都会将相应的语句写到redo log中,如果主机断电,那么再次启动时可通过redo log回复。

       拓展:redo log也需要在事务提交时将日志写入磁盘,它比缓冲池写入快的原因有两点:

               redo log是追加文件写,属于顺序I0,缓冲池是属于随机I0,且刷脏是以页为单位,

        有一点修改就要整页写入

3.事务具有隔离性:事务和事务之间是互相隔离的,各个事务之间不能互相干扰。而事务并发问题就是隔离性的问题

4.事务具有一致性:事务在执行之前和执行之后,数据库的状态必须保持一致。这意味着事务执行过程中的任何变化都必须满足预定的规则和约束。前面提到的原子性、持久性和隔离性,都是为了保证数据库状态的一致性。

事务的并发问题

1.脏读:事务A读取到了事务B修改但未提交的数据

2.不可重复读:是指在一个事务内,多次读取同一数据,但是数据的值发生了改变

3.幻读:指的是在一个事务中,多次查询同一个范围的数据,却发现有新增或者减少的行。这是因为在这个事务进行的过程中,另一个事务插入或者删除了符合查询条件的数据,导致前后两次查询结果不一致。

总结不可重复读和幻读的区别:

五、事务的隔离级别
mysql中的四种事务隔离级别如下:

1.read uncommitted (读未提交数据):允许事务读取未被其他事务提交的变更。(脏读、不可重复读和幻读的问题都会出现)

#设置读未提交的隔离级别

set global transaction isolation level read uncommitted;
#查看当前隔离级别
select @@global.tx isolation,@@tx isolation;(旧版本)

SELECT @@global.transaction_isolation, @@transaction_isolation;(5.7.20版本之后)


2.read commited(读已提交数据):只允许事务读取已经被其他事务提交的变更。(可以避免脏读,但不可重复读和幻读的问题仍然可能出现)

#设置读以提交的隔离级别

set global transaction isolation level read committed;

插入但是没有提交,是读不出来的,提交之后才能够读出来

3.repeatable read(可重复读):确保事务可以多次从一个字段中读取相同的值,在这个事务持续期间,禁止其他事务对这个字段进行更新(update)。(可以避免脏读和不可重复读,但幻读仍然存在)

#设置可重复读的隔离级别

set global transaction isolation level repeatable read;

可见,无论是删除还是添加,commit后都是成功的,但是另一边却还是读出原来的数据,这就是可重复读,读取的是备份数据不是真正的数据。

4.serializable(串行化):确保事务可以从一个表中读取相同的行,在这个事务持续期间,禁止其他事务对该表执行插入、更新和删除操作,所有并发问题都可避免,但性能十分低下(因为你不完成就都不可以弄,效率太低)

#设置串行化的隔离级别

set global transaction isolation level serializable;

隔离级别与一致性的关系

  • 16
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值