MySQL事务

MySQL事务

事务的概念

一个事务是由一条或者多条对数据库操作的SQL语句所组成的一个不可分割的单元,只有当事务中的所有操作都正常执行完了,整个事务才会被提交给数据库;如果有部分事务处理失败,那么事务就要回退到最初的状态,因此,事务要么全部执行成功,要么全部失败。
比如在一笔A用户和B用户交易的过程中,A给B转账,我们需要两条SQL语句。一条是A用户的账户减去付款金额,另一条就是B的账号加上收款金额。事务机制保证了这两条SQL要么都执行成功,要么都失败,不存在一条成功执行,另一条失败的情况。
事务的几个基本概念如下:
1、事务是一组SQL语句的执行,要么全部成功,要么全部失败,不能出现部分成功,部分失败的结果。保证事务执行的原子操作。
2、事务的所有SQL语句全部执行成功,才能提交(commit)事务,把结果写回磁盘上。
3、事务执行过程中,有的SQL出现错误,那么事务必须要回滚(rollback)到最初的状态。

事务的ACID特性

每一个事务必须满足下面的4个特性:
事务的原子性(Atomic):
事务是一个不可分割的整体,事务必须具有原子特性,及当数据修改时,要么全执行,要么全不执行,即不允许事务部分的完成。

事务的一致性(Consistency):
一个事务执行之前和执行之后,数据库数据必须保持一致性状态。数据库的一致性状态必须由用户来负责,由并发控制机制实现。就拿网上购物来说,你只有让商品出库,又让商品进入顾客的购物车才能构成一个完整的事务。

事务的隔离性(Isolation):
当两个或者多个事务并发执行时,为了保证数据的安全性,将一个事物内部的操作与其它事务的操作隔离起来,不被其它正在执行的事务所看到,使得并发执行的各个事务之间不能互相影响。

事务的持久性(Durability):
事务完成(commit)以后,DBMS保证它对数据库中的数据的修改是永久性的,即使数据库因为故障出错,也应该能够恢复数据!

InnoDB存储引擎

MySQL支持插件式的存储引擎,其中的InnoDB 存储引擎提供了具有提交、回滚和崩溃恢复能力的事务安全机制。而MyISAM存储是不支持事务的。
为什么InnoDB能支持事务呢?
支持事务机制必须要能满足事务的ACID特性。
在事务执行时,MySQL是现在cache缓存上写,当事务提交后,在事务提交后再把缓存上的数据写到磁盘上,而磁盘操作是比较耗时、且缓存上的数据是无法持久化的。在意外情况下,比如MySQLServer断电或者宕机了,此时缓存上的数据就丢了,但此时事务commit已经提交成功,用户理所应当的认为事务的操作成功了。MySQL通过重做日志redo log机制来保证事务提交成功后,数据能保存到磁盘上。
对于事务在执行过程中,意外宕机的情况,通过回滚日志undo log机制来回滚到事务开启前的状态。
所以对MySQL来说,最重要的是日志,而不是数据。
事务的ACD(原子性、一致性、持久性)由redo log和undo log来保证,对于事务的隔离性,由InnoDB的锁机制来保证,不同的隔离级别都有不同的优缺点。

事务并发存在的问题

事务处理不经隔离,并发执行事务时通常会发生以下的问题:
脏读(Dirty Read):一个事务读取了另一个事务未提交的数据。例如当事务A和事务B并发执行时,当事务A更新后,事务B查询读取到A尚未提交的数据,此时事务A回滚,则事务B读到的数据就是无效的脏数据。(事务B读取了事务A尚未提交的数据)

不可重复读(NonRepeatable Read):一个事务的操作导致另一个事务前后两次读取到不同的数据。例如当事务A和事务B并发执行时,当事务B查询读取数据后,事务A更新操作更改事务B查询到的数据,此时事务B再次去读该数据,发现前后两次读的数据不一样。(事务B读取了事务A已提交的数据)

虚读(Phantom Read)幻读:一个事务的操作导致另一个事务前后两次查询的结果数据量不同。例如当事务A和事务B并发执行时,当事务B查询读取数据后,事务A新增或者删除了一条满足事务B查询条件的记录,此时事务B再去查询,发现查询到前一次不存在的记录,或者前一次查询的一些记录不见了。(事务B读取了事务A新增加的数据或者读不到事务A删除的数据)

事务的隔离级别

MySQL支持的四种隔离级别是:
1、READ-UNCOMMITTED。未提交读。说明在提交前一个事务可以看到另一个事务的变化。这样读脏数据,不可重复读和虚读都是被允许的。
2、READ-COMMITTED。已提交读。说明读取未提交的数据是不允许的。这个级别仍然允许不可重复读和虚读产生。
3、REPEATABLE-READ。可重复读。说明事务保证能够再次读取相同的数据而不会失败,但虚读仍然会出现。
4、SERIALIZABLE。串行化。是最高的事务级别,它防止读脏数据,不可重复读和虚读。
在这里插入图片描述
事务隔离级别越高,为避免冲突所花费的性能也就越多。
在“可重复读”级别,实际上可以解决部分的虚读问题,但是不能防止update更新产生的虚读问题,要禁止虚读产生,还是需要设置串行化隔离级别。

MySQL的事务处理命令

select @@autocommit; 可以查看MySQL是否自动提交事务。
在这里插入图片描述
0代表手动手动提交事务,1表示自动提交事务。设置为自动提交事务时,一条SQL被当作一个事务处理流程。
事务相关命令:

select @@autocommit;//查看MySQL是否自动提交事务
set autocommit=0; //设置事务提交方式为手动提交
begin; //开启一个事务
commit; //提交一个事务
rollback ; //回滚一个事务到初始的位置
savepoint point1; //设置一个名字为point1的保存点
rollback to point1; //事务回滚到保存点point1,而不是回滚到初始状态
set transaction_isolation='REPEATABLE-READ'; //设置事务的隔离级别
select @@transaction_isolation; //查询事务的隔离级别

在这里插入图片描述
MySQL 的默认隔离级别是REPEATABLE-READ可重复读。

不同隔离级别测试验证

READ-UNCOMMITTED。未提交读:

在这里插入图片描述
可以看到左边的事务A还没有提交,右边的事务B不仅读到了事务A未提交的数据(脏读),且两次读到的id=1的数据不一致(不可重复读),两次读到的记录条数也不同(幻读)。
在READ-UNCOMMITTED。未提交读隔离级别下,脏读、不可重复读、幻读都是有可能发生的!

READ-COMMITTED。已提交读

在这里插入图片描述
左边的事务A未提交记录修改,事务B是并未读到未提交的数据,已提交读隔离级别下,是无法读到事务未提交的记录的。
在这里插入图片描述
接着事务A提交,事务B再去读user表的数据,两次读到的id=1的数据不一致(不可重复读),两次读到的记录条数也不同(幻读)。
已提交读解决了脏读问题,但不可重复读和幻读现象还是会出现。

REPEATABLE-READ。可重复读

在这里插入图片描述
在这里插入图片描述
事务B分别在事务A开始前、insert和update执行后、commit执行后分别进行三次select * from user;,三次查询的结果都一致。没有出现脏读、不可重复读和幻读现象。但是:
在这里插入图片描述
对id=8的记录进行update后再查询,就出现了幻读现象。
可重复读不仅解决了脏读和不可重复读现象,同时也解决了部分幻读现象。

SERIALIZABLE。串行化

在这里插入图片描述
SERIALIZABLE串行化级别下,事务都是串行执行的,事务B获取读锁后,事务A要去更新锁住的资源,只能等待事务B先执行完。虽然解决了幻读问题,但事务的并发处理能力过于低下,一般都不会使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
MySQL 事务是指一组数据库操作,这些操作要么全部执行,要么全部不执行,其目的是保证在并发环境下,数据的一致性和完整性。MySQL 事务具有 ACID 性质,即原子性、一致性、隔离性和持久性。 MySQL 中使用事务需要使用 BEGIN、COMMIT 和 ROLLBACK 语句,其中 BEGIN 表示开启一个事务,COMMIT 表示提交事务,ROLLBACK 表示回滚事务事务的基本语法如下: ``` BEGIN; -- 执行一组数据库操作 COMMIT; -- 提交事务 -- 或者 ROLLBACK; -- 回滚事务 ``` 在 MySQL 中,事务的隔离级别分为四个等级,分别是 Read Uncommitted、Read Committed、Repeatable Read 和 Serializable。隔离级别越高,数据的一致性和完整性越高,但同时也会影响数据库的性能。 MySQL 事务的 ACID 性质有以下含义: 1. 原子性(Atomicity):事务中的所有操作要么全部执行成功,要么全部失败回滚,不会只执行其中的一部分操作。 2. 一致性(Consistency):事务执行前后,数据库中的数据必须保持一致性状态,即满足数据库的约束条件和完整性规则。 3. 隔离性(Isolation):事务之间应该是相互隔离的,一个事务的执行不应该被其他事务干扰,保证事务之间的数据相互独立。 4. 持久性(Durability):事务提交后,对数据库的修改应该是永久性的,即使出现系统故障或电源故障,也不应该对数据产生影响。 总之,MySQL 事务一组数据库操作,具有 ACID 性质,可以通过 BEGIN、COMMIT 和 ROLLBACK 语句来实现,隔离级别越高,数据的一致性和完整性越高,但同时也会影响数据库的性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_200_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值