MySQL--事务

Updated on in 程序人生 with 0 views and 0 comments

一、简介

MySQL事务是一组DML(select\update\delete)语句的集合,mysql数据库中InnoDB存储引擎支持开启事务,MyISAM不支持。MySQL事务默认自动提交,可通过begin、commit、rollback手动控制。

二、特性

事务有四大特性,原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)

2.1 原子性

事务中的操作要么全执行,要么全不执行

2.2 一致性

数据库的完整性约束没有被破坏,事务执行的前后都是合法的数据状态

eg:甲乙两个银行账户的总金额再转账前后必须一致,只允许事务执行过程中短暂出现不一致的情况

2.3 隔离性

隔离性是指,事务内部的操作与其他事务是隔离的,并发执行的各个事务之间不能互相干扰

2.4 持久性

持久性是指事务一旦提交,它对数据库的改变就应该是永久性的

三、事务并发的问题

3.1 读脏

读到了其他事务未提交的数据

image.png

3.2 不可重复度

一个事务内的多次查询返回了不同的结果,这是由于在查询过程中,数据被另外一个事务修改并提交了

image.png

3.3 幻读

幻读是指在一个事务内按照相同的查询条件进行了两次查询,但第二次查询发现了第一次查询不存在的新行(即“幻影行”)

image.png

四、事务隔离级别

4.1 读未提交

事务可以读取到其他事务尚未提交的数据变更,即脏读(Dirty Read)

4.2 读已提交

事务只会读取到其他事务已经提交的数据,解决了脏读的问题,但任然会出现不可重复度和幻读的问题

4.3 可重复读

一个事务多次读取的同一个数据返回的结果相同,但任然会有幻读

4.4 可串行化

在此级别下,事务会按序列化的顺序执行,相当于每个事务都会获取所有受影响数据上的锁,直到事务结束。这样可以防止所有类型的并发问题,包括脏读、不可重复读以及幻读,但代价是可能会导致更高的锁定开销和更低的并发性能。

image.png

五、更新丢失

MySQL的InnoDB引擎默认隔离级别是可重复读,可以处理读脏和不可重复读问题,但是会出现幻读和更新丢失的问题

eg:

  1. 事务A开始并执行 UPDATE 操作,将某行记录的值从 X 改为 Y
  2. 同时,事务B也对同一条记录执行 UPDATE 操作,将其值从 X 改为 Z
  3. 如果事务B先于事务A提交,则数据库中的该记录值现在是 Z
  4. 当事务A随后提交时,其更新操作已失效,因为基于事务B提交后的状态进行,所以事务A试图将 X 更新为 Y 的动作无法反映到最终的数据中,从而导致了事务A的更新丢失。

解决方法

  1. 适用序列化隔离级别
  2. 确保在更新数据前对需要修改的行或表进行适当的锁定,如使用行级锁或表级锁,确保在更新期间其他事务不能修改这些数据
  3. 通过版本号或者时间戳来实现,每次更新时检查版本号是否与最初读取数据时一致,若不一致则拒绝更新,这样可以避免更新丢失
  4. 在事务开始时就立即获取所需的锁,直到事务结束才释放,这种方式可以确保在整个事务处理过程中,锁定的资源不会被其他事务修改

标题:MySQL--事务
作者:wenyl
地址:http://www.wenyoulong.com/articles/2024/01/16/1705394149285.html