SQL事务

1、什么是事务(transaction)?

事务:就是一个完整的业务逻辑。
什么是一个完整的业务逻辑?
假设转账,从A账户向B账户中转账10000
将A账户的钱减去10000
将B账户的钱加上10000,这就是一个完整的业务逻辑。
以上的操作是一个最小的工作单元,要么同时成功,要么同时失败,不可再分。
这两个update语句要求必须同时成功或者同时失败,这样才能保证钱是正确的。

2、事务的相关语句

只有DML语句才会有事务这一说,其它语句和事务无关!!!
insert
delete
update
只有以上的三个语句和事务有关系,其它都没有关系。
因为 只有以上的三个语句是数据库表中数据进行增、删、改的。
只要你的操作一旦涉及到数据的增、删、改,那么就一定要考虑安全问题。
数据安全第一位!!!
在这里插入图片描述
假设所有的业务,只要一条DML语句就能完成,还有必要存在事务机制吗?

不需要

正是因为做某件事的时候,需要多条DML语句共同联合起来才能完成,所以需要事务的存在。如果任何一件复杂的事儿都能一条DM语句搞定,那么事务则没有存在的价值了
到底什么是事务呢?
说到底,说到本质上,一个事务其实就是多条DM语句同时成功,或者同时失败!

3、事务的同时失败和成功

事务是如何同时失败和成功的?
InnoDB存储引擎:提供一组用来记录事务性活动的日志文件
案例:假设这是一个事务

事务开启了:
insert
insert
insert
delete
update
update
update
事务结束了!

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

提交事务:

清空事务性活动的日志文件,将数据全部彻底持久化到数据库表中。
提交事务标志着,事务的结束。并且是一种全都成功的结束。

回滚事务:

将之前所有的DML操作全部撤销,并且清空事务性活动的日志文件。
回滚事务标志着,事务的结束。并且是一种全都失败的结束。

4、事务的提交和回滚

事务提交:commit
事务回滚:rollback
这里要注意的是:

mysql默认情况下是支持自动提交事务的,而回滚只能回滚到上一次的提交点。

自动提交即每执行一条DML语句,则提交一次!
案例:

select * from room2;
delete from room2;
rollback;
select * from room2;

在这里插入图片描述
这里能看到明明已经进行了回滚,room2这张表中的数据仍然还是被delete了,这就是因为mysql中默认自动提交的,即delete之后便会自动进行一次提交,即这个事务已经进行提交并结束,所以rollback回滚不了。那么便需要开启事务,关闭原有的自动提交机制:

关闭自动提交机制,开启事务:start transaction;

案例:
能看到经过回滚,插入的数据并没有插入。

start transaction;
insert into room2 values(544,6,'wang',231);
rollback;

在这里插入图片描述

5、事务的四大特性(ACID):

A:原子性:
说明事务是最小的工作单元。不可再分。
C:一致性:
所有事务要求,在同一个事务当中,所有操作必须同时成功,或者同时失败,以保证数据的一致性。
I:隔离性:
A事务和B事务之间县有一定的隔离教室A和教室B之间有一道墙,这道墙就是隔离性。
A事务在操作一张表的时候,另一个事务B也操作这张表会那样?? ?
D:持久性
事务最终结束的一个保障。事务提交,就相当于将没有保存到硬盘上的数据保存到硬盘上!
重点:隔离性
A教室和B教室中间有一道墙,这道墙可以很厚,也可以很薄。这就是事务的隔离级别。
这道墙越厚,表示隔离级别就越高。
事务和事务之间的隔离级别有哪些呢?4个级别:

1)读未提交: read uncommitted(事务的最低隔离级别)《没有提交就读到了》
	什么是读未提交?
		事务A可以读取到事务B未提交的数据。
		这种隔离级别存在的问题就是:脏读现象! (Dirty Read),我们称读到了脏数据。
		这种隔离级别一般都是理论上的,大多数的数据库隔离级别都是二档起步!2)读已提交: read committed《提交之后才能读到》
	什么是读已提交?
		事务A只能读取到事务B提交之后的数据。
	这种隔离级别解决了什么问题?
		解决了脏读的现象。
	这种隔离级别存在什么问题?
		不可重复读取数据。
		在事务开启之后,第一次读到的数据是3条,当前事务还没有结束,
		可能第二次再读取的时候,读到的数据是4条,3不等于4称为不可重复读取。
	这种隔离级别是比较真实的数据,每一次读到的数据是绝对的真实。
	oracle中默认的事务级别就是这个!!!!
(3)可重复读: repeatable read《提交之后也读不到,永远读取的都是刚开启事务时的数据》
	什么是可重复读取?
	事务A开启之后,不管是多久,每一次在事务A中读取到的数据都是一致的。
	即使事务B将数据已经修改,并且提交了,
	事务A读取到的数据还是没有发生改变,这就是可重复读。
	早晨9点开始开启了事务,只要事务不结束,到晚上9点,读到的数据还是那样!
	读到的是假象(备份或者快照),不够绝对的真实。
	mysql中默认的事务级别就是这个!!!!!
(4)序列化/串行化: serializable(事务的最高隔离级别)
	这是最高隔离级别,效率最低。解决了所有的问题。
	这种隔离级别表示事务排队,不能并发!
	在执行一个事务的同时,其他事务无法执行!
	synchronized,线程同步(事务同步)!
	每一次读取到的数据都是最真实的,并且效率是最低的。

查看当前mysql隔离级别(可重复读)

select @@transaction_isolation;

在这里插入图片描述
设置当前全局隔离级别为读未提交:

set global transaction isolation level read uncommitted;
read committed; //读已提交
repeatable read; //可重复读
serializable; //序列化

在这里插入图片描述
设置之后重新退出再次登录查询:能看到被更改为读未提交。
在这里插入图片描述
测试读未提交:打开两个终端窗口

第一个窗口:
1、进入数据库查询表,明显能看到是空表
	select  * from room;
2、关闭mysql默认提交事务
	start transaction;
第二个窗口:
1、关闭mysql默认提交事务
	start transaction;
2、对表进行插入,但不提交:
	insert into room values(123,'wang',561);
第一个窗口:
1、对表进行查询能发现其中有数据了:
	select  * from room;

在这里插入图片描述
测试(读已提交):

第一个窗口:
1、进入数据库查询表,明显能看到是空表
	select  * from room;
2、关闭mysql默认提交事务
	start transaction;
第二个窗口:
1、关闭mysql默认提交事务
	start transaction;
2、对表进行插入,但不提交:
	insert into room values(123,'wang',561);
第一个窗口:
1、对表进行查询,没有数据:
	select  * from room;
第二个窗口:
1、对insert进行提交
	commit;
第一个窗口
	1、对表进行查询:发现有数据了
	select * from room;

在这里插入图片描述
测试(可重复读):

第一个窗口:
1、将隔离等级设置为可重复读:
set global transaction isolation level repeatable read;
2、启动事务,关闭自动提交:
start transaction;
3、查表有数据
select * from room;
第二个窗口:
1、启动事务:
start transaction;
2、删除表格:
delete from room;
3、提交:
commit;
第一个窗口:
1、再此进行查询:仍然有数据
select * from room;

在这里插入图片描述
测试:(序列化)

第一个窗口:
1、将隔离级别设置成序列化:
set global transaction isolation level serializable;
2、启动事务:
start transaction;
3、插入数据
insert room values(12,'你好',56);
第二个窗口:
1、启动事务:
start transaction;
2、查询表,发现无法继续运行了,一直在光标闪动
select * from room;
第一个窗口:
1、提交事务:提交完成后,第二个窗口自动输出查询结果
commit;

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值