MySQL8.0学习笔记(10)——transaction

本文介绍了MySQL8.0中事务的基础知识,包括事务的定义、四大特性(原子性、一致性、隔离性、持久性)。详细讲解了如何创建和管理事务,并探讨了事务的隔离级别及其在并发控制中的作用。此外,还通过实例分析了死锁现象,并提出了避免死锁的策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

transaction

简介

  • 事务:一个最小的不可再分的工作单元;通常一个事务对应一个完整的业务(例如银行账户转账业务,该业务就是一个最小的工作单元)
  • 一个完整的业务需要批量的DML(insert、update、delete)语句共同联合完成
  • 事务只和DML语句有关,或者说DML语句才有事务。这个和业务逻辑有关,业务逻辑不同,DML语句的个数不同

事务的四大特征

  • 原子性(A):事务是最小单位,不可再分,当执行的语句中间出错时会进行回滚
  • 一致性©:事务要求所有的DML语句操作的时候,必须保证同时成功或者同时失败
  • 隔离性(I):事务A和事务B之间具有隔离性
  • 持久性(D):是事务的保证,事务终结的标志(内存的数据持久到硬盘文件中)

创建transaction

use sql_store;
start transaction;

insert into orders(customer_id,order_date,status)
values(1,'2019-01-01',1);

insert into order_items
values(last_insert_id(),1,1,1);
-- 手动进行提交,保证修改存入数据池
commit	
-- rollback 回滚事务的所有操作

对于对同一个表操作的两个DML事务,一定会先执行完一个再执行另外一个

isolation

为了解决读写的并发性(concurrency),对于事务来说,原子性保证了其写的并发性,但在某些情况下(一个读一个写)需要自己来进行处理来保持两个事务的隔离性(isolation)。

  1. 事物A和事物B之间具有一定的隔离性
  2. 隔离性有隔离级别(4个)
    1. 读未提交:read uncommitted
    2. 读已提交:read committed
    3. 可重复读:repeatable read
    4. 串行化:serializable
  • read uncommitted
- 事物A和事物B,事物A未提交的数据,事物B可以读取到
- 这里读取到的数据叫做“脏数据”
- 这种隔离级别最低,这种级别一般是在理论上存在,数据库隔离级别一般都高于该级别
  • read committed
- 事物A和事物B,事物A提交的数据,事物B才能读取到
- 这种隔离级别高于读未提交
- 换句话说,对方事物提交之后的数据,我当前事物才能读取到
- 这种级别可以避免“脏数据”
- 这种隔离级别会导致“不可重复读取”
- Oracle默认隔离级别
  • repeatable read
- 事务A和事务B,事务A提交之后的数据,事务B读取不到
- 事务B是可重复读取数据,在初始就形成一个数据快照,以那个快照为基准执行
- 这种隔离级别高于读已提交
- 换句话说,对方提交之后的数据,我还是读取不到
- 这种隔离级别可以避免“不可重复读取”,达到可重复读取
- 比如read uncommitted和read uncommitted读到数据是同一个
- MySQL默认级别
- 虽然可以达到可重复读取,但是会导致“幻像读”
- 所谓幻像读即是事务A通过提交的数据某一行已经满足事务B的where条件(假如存在),但对于事务B来说满足条件的那一行还是无法被执行。
  • serializable
- 事务A和事务B,事务A在操作数据库时,事务B只能排队等待
- 这种隔离级别很少使用,吞吐量太低,用户体验差
- 这种级别可以避免“幻像读”,每一次读取的都是数据库中真实存在数据,事务A与事务B串行,而不并发

对于隔离等级能够预防的问题
在这里插入图片描述

  • 查看现在的隔离等级
show variable like 'transaction_isolation';
  • 改变隔离等级(serializable)
//只会对后面一个事务起作用
set transaction isolation level serializable;
//在当前session or connection未来所有事务都起作用
set session transaction isolation level serializable;
//对所有session or connection未来所有事务都起作用
set global transaction isolation level serializable;

DeadLock

死锁的概念,举例一下在Mysql中出现的情况

  • session1
use sql_store;
start transaction;
update customers set state = 'VA' where customer_id = 1;
update orders set status = 1 where order_id = 1;
commit;
  • session2
use sql_store;
start transaction;
update orders set status = 1 where order_id = 1;
update customers set state = 'VA' where customer_id = 1;
commit;

当session1执行完第三句的时候,mysql对customers 加锁,此时session2执行完地句对orders 进行加锁,session1获取不到orders 的锁一直等待,session2获取不到customers 的锁等待形成死锁。

解决方法

  • 保证两个事务对表的操作顺序一直
  • 减少每个事务的持续时间
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值