MySQL事务


MySQL事务

一、事务介绍

什么是事务

一个事务是一个完整的业务逻辑单元,不可再分。

比如:银行账户转账,从A账户向B账户转账10000.需要执行两条update语句:
update t_act set balance = balance - 10000 where actno = ‘act-001’;
update t_act set balance = balance + 10000 where actno = ‘act-002’;

以上两条DML语句必须同时成功,或者同时失败,不允许出现一条成功,一条失败。

要想保证以上的两条DML语句同时成功或者同时失败,那么就需要使用数据库的“事务机制”。

应用场景

事物的和事务相关的语句只有DML语句。(insert delete update)—— 事务之和对数据产生变化的操作有关
为什么?因为它们这三个语句都是和数据库表当中的“数据”相关的。
事务的存在是为了保证数据的完整性,安全性。

如果只有一条DML语句,还需要事务机制嘛?

不需要!

但实际情况不是这样的,通常一个“事儿(事务【业务】)”需要多条DML语句共同联合完成。

综上所述:事务机制就是在处理某一个业务(事务)时多条DML语句同时成功或者同时失败,保证数据的完整性,安全性

事务如何实现

事务如何做到多条DML语句同时成功或者同时失败?

MySQL中的InnoDB存储引擎:提供了一组用来记录事务活动的日志文件(log)

事务开启了!

insert

insert

update

delete

事务结束了!

在事务执行的1过程中,每一条DML语句都会记录到事务性活动的日志文件中,在事务的执行过程中,我们可以提交事务,也可以回滚事务。

提交事务?

提交事务,就会清空事务性活动的日志文件,将数据全部彻底持久化到数据库表中。

提交事务标志着,事务的结束!并且是一种全部成功(所有DML全部成功)的结束

事务回滚?

将之前的所有DML全部撤销,并且清空事务性活动的日志文件。

回滚事务,标志着事物的结束!并且是一种全部失败(所有DML全部失败)的结束

怎么提交和回滚事务

  • 事务提交:commit
  • 事务回滚:rollback ——(回滚到上一次commit的地方)

测试:MySQL中的事务默认提交方式是怎么样的?手动提交还是自动提交呢?——自动提交

​ 自动提交?—— 没执行一条DML语句,就会提交一次事务

在这里插入图片描述

上述我们删除表中的数据后,进行回滚,并不能将原来的数据恢复,那是因为,在执行delete语句后,事务自动提交(默认),然后就会清空事务性活动的日志文件,当进行回滚时无法从日志文件中拿到并恢复数据!

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

我们如何关闭MySQL的默认自动提交事务,而是自己手动提交事务呢?

关闭自动提交事务命令(我们自己开启事务),先执行这一条命令:start transaction

然后就是DML语句

最后提交事务

事务回滚:

在这里插入图片描述

提交事务与回滚事务:滚不回去了!

在这里插入图片描述

二、事务的特性

一个事务就是完成一件事(一个完整的业务逻辑)

事务有四大特性:ACID

  • A:原子性:事务是最小的工作单元,不可再分。
  • C:一致性:事务必须保证多条DML语句同时成功或者同时失败。
  • I:隔离性:事务A与事务B之间具有隔离。
  • D:持久性:持久性说的是最终数据必须持久化到硬盘文件中,事务才算成功的结束。(真正存到数据库中)

三、事务的隔离性即演示

1. 隔离性的4个级别

事务隔离性存在隔离级别,理论上隔离级别包括4个:

  • 第一级别:读未提交(read uncommitted
    对方事务还没有提交,我们当前事务可以读取到对方未提交的数据。
    读未提交存在脏读(Dirty Read)现象:表示读到了脏的数据。
  • 第二级别:读已提交(read committed)
    对方事务提交之后的数据我方可以读取到。
    这种隔离级别解决了: 脏读现象没有了。
    读已提交存在的问题是:不可重复读。
  • 第三级别:可重复读(repeatable read)————(MySQL默认的事务隔离级别)
    这种隔离级别解决了:不可重复读问题。
    这种隔离级别存在的问题是:读取到的数据是幻象。
  • 第四级别:序列化读/串行化读(serializable)
    解决了所有问题。
    效率低。需要事务排队。

MySQL命令行的默认配置中事务都是自动提交的,即执行SQL语句就会马上执行COMMIT操作。可以用命令START TRANSACTION开始一个事务。

我们可以通过下面命令设置事务隔离级别。

SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED|READ COMMITTED|REPEATABLE READ|SERIALIZABLE]
1级别:读未提交
	set global transaction isolation level read uncommitted;2级别:读已提交
	set global transaction isolation level read committed;3级别:可重复读
	set global transaction isolation level repeatable read;
cd C:\Program Files\MySQL\MySQL Server 8.0\bin

查看当前事务级别:

select @@transaction_isolation;

我们再来看一下我们在实际操作中使用到的一些并发控制语句:

  • START TRANSACTION | BEGIN :显示的开启一个事务。
  • COMMIT:提交事务,使得对数据库做的所有修改成为永久性。
  • ROLLBACK:回滚到结束用户的事务,并撤销正在进行的所有未提交的修改。

2.隔离性演示

(1)第一级别

第一级别:读未提交(read uncommitted
对方事务还没有提交,我们当前事务可以读取到对方未提交的数据。
读未提交存在脏读(Dirty Read)现象:表示读到了脏的数据。

事务A--------------------------------------事务B

窗口A和窗口B并行进行测试检验!

1、在窗口A将全局事务级别设为 read uncommitted

	set global transaction isolation level read uncommitted;

成功,退出,再进入

查看级别等级——设置成功

select @@transaction_isolation;

在这里插入图片描述

2、同时开两个命令窗口,登录数据库,进入到我们测试用的数据库

窗口A:

1、开启事务

start transaction;

2、查一下数据

select * from user;

# 表此时为空

窗口B:

1、开启事务

start transaction;

2、插入数据(未提交(事务未提交,没有commit))

insert into user values("张三");

再回到窗口A:查看数据,发现数据查出来了!!!

在这里插入图片描述

第一级别:

第一级别:读未提交(read uncommitted
对方事务还没有提交,我们当前事务可以读取到对方未提交的数据。

(2)第二级别

事务A--------------------------------------事务B

窗口A和窗口B并行进行测试检验!

1、在窗口A将全局事务级别设为 read committed

	set global transaction isolation level read committed;

成功,退出,再进入

查看级别等级——设置成功

select @@transaction_isolation;

在这里插入图片描述

2、同时开两个命令窗口,登录数据库,进入到我们测试用的数据库

窗口A:

1、开启事务

start transaction;

2、查一下数据

select * from user;

# 表此时为空

窗口B:

1、开启事务

start transaction;

2、插入数据(未提交(事务未提交,没有commit))

insert into user values("李四");

3、再回到窗口A:查看数据,数据未查出来!!!

在这里插入图片描述

4、回到窗口B,进行事务提交

commit;

​ 5、再回到窗口A:查看数据,数据查出来了!!!

在这里插入图片描述

第二级别

1第二级别:读已提交(read committed)
对方事务提交之后的数据我方可以读取到。
这种隔离级别解决了: 脏读现象没有了。
读已提交存在的问题是:不可重复读。

(3)第三级别

事务A--------------------------------------事务B

窗口A和窗口B并行进行测试检验!

1、在窗口A将全局事务级别设为 repeatable read

	set global transaction isolation level repeatable read;

成功,退出,再登录进入

查看级别等级——设置成功

select @@transaction_isolation;

在这里插入图片描述

2、同时开两个命令窗口,登录数据库,进入到我们测试用的数据库

窗口A:

我们事先先插入一条数据:

insert into user values("6666");

1、开启事务

start transaction;

2、查一下数据

select * from user;

# 表此时有一条数据6666

窗口B:

1、开启事务

start transaction;

2、插入数据(未提交(事务未提交,没有commit))

insert into user values("李四");
insert into user values("李四");
insert into user values("李四");

在这里插入图片描述

4、提交事务

commit;

窗口A:

5、再回到窗口A:查看数据,数据未查出来!!!

在这里插入图片描述

6、窗口A中,提交事务后,就可以看到新数据了

在这里插入图片描述

1第三级别:可重复读(repeatable read)
这种隔离级别解决了:不可重复读问题。
这种隔离级别存在的问题是:读取到的数据是幻象。

总结:两个事务是独立的,当对同一张表同时开启事务,事务B中进行DML语句,commit结束事务B后,只要事务A此时还没结束,那么A事务中查询到的数据都是事务B提交前的数据(两个事务同时进行时,事务独立开来了,互不影响的(第三级别)),只有当事务Acommit后,事务B中的DML语句产生的影响才会作用到事务A,此时查询到的数据是更新后的!

(4)第四级别

窗口A和窗口B并行进行测试检验!

1、在窗口A将全局事务级别设为 serializable

	set global transaction isolation level serializable;

成功,退出,再进入

查看级别等级——设置成功

select @@transaction_isolation;

在这里插入图片描述

2、同时开两个命令窗口,登录数据库,进入到我们测试用的数据库

窗口A:

1、开启事务

start transaction;

2、查一下数据

select * from user;

# 表此时为空

3、插入数据(未提交(事务未提交,没有commit)—— 事务A没结束)

insert into user values("张三");

窗口B:

1、开启事务(事务要同时开启的)

start transaction;

2、查询数据,发现窗口B,光标卡住了

因为两个事务同时操作这张表了,第四级别四需要排队的!!!

在这里插入图片描述

窗口A:

再回到窗口A:结束事务——发现窗口B立即查出数据来了(说明第四级别事务需要排队!!!!)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 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
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值