mysql事务 作者:哇塞大嘴好帥 作者:哇塞大嘴好帥(哇塞大嘴好帅)
1.什么是事务? ? 这种把多条语句作为一个整体进行操作被称为数据库事务,要不这个整体都运行成功,要不都运行失败。
2.事务原则:ACID原则
2.1原子性(Atomicity)
? 将所有SQL作为原子工作单元(事务是最小的执行单位)执行,要么全部执行,要么全部不起作用。
? 做个例子:比如A账户在银行给B账户转了500万,那么B账户就接收到了500万,不可能A账户把钱转出去了B账户没有收到。也不可能A账户没有转钱B账户收到了500万
2.2一致性
? 当我们事务没有提交的时候,我们数据库发生了宕机或者断电, 当我们再次进入数据库的时候,数据是事务操作前的数据。
? 当我们事务提交之后,我们数据库发生了宕机或者断电,当我们再次进入数据库的时候,数据是事务操作后的数据。
? 总结:事务前事务后数据的完整性必须保持一致。
2.3隔离性(Isolation)
? 并发访问数据库的时候,一个用户的事务不能被其他事务所干扰,一个用户的事务不能被其他事务所干扰,各并发事务之间数据库是独立的
2.3.1隔离级别划分
级别 | 描述 |
---|---|
Read Uncommited(读取未提交) | 最低的隔离级别,允许读取未提交的数据变更,可能会导致脏读、幻读、不可重复读。 |
Read Committed(读取已提交) | 允许读取并发事务已提交的数据,可以组织藏独,但是幻读或不可重复读仍有可能发生。 |
Repeatable Read(可重复读) | 对同一字段的多次读取结果都是一直,除非数据是被本身事务自己修改的,可以组织藏独和不可重复读,但是幻读依然可能出现。 |
Serializable(可串行化) | 最高的隔离界别,完全服役ACID的隔离级别,所有事务依次逐个执行,这样事务之间就完全不可能产生干扰,可以防止脏读,幻读,不可重复读。 |
2.3.3 不可重复读(Non-repeateble read) ? 在A本事务中,对自己微操作过的数据,进行了多次读取,结果发i西安了不一致或者记录不存在的情况(破坏了一致性,只有update和delete会发生)
2.3.4 幻读(Phantom Read) ? 对自己为操作过的数据,进行了多次读取,第一次读取的时候,记录不存在,第二次读取的时候记录出现了(破坏了一致性,只有insert会导致)
2.4持久性
? 一个事务一旦提交,它对数据库中数据的改变就是永久性的,不会因为断电宕机导致事务不生效
3.模拟隔离性 3.1 Read Uncommited
首先将数据隔离级别设置为Read Uncommited
set SESSION transaction ISOLATION LEVEL READ uncommitted
start transaction
事务A查询此test1表
select *from test1
id | userid | mount |
---|---|---|
1 | 1 | 1111 |
2 | 2 | 2222 |
3 | 3 | 3333 |
update test1 set mount = 888 where id =1;
select *from test1
id | userid | mount |
---|---|---|
1 | 1 | 8888 |
select *from test1
id | userid | mount |
---|---|---|
1 | 1 | 8888 |
3.2 Read commited
更改事务级别
set SESSION transaction ISOLATION LEVEL READ committed;
start transaction
这时候我们事件B修改值并且没有提交
update test1 set amount= 12 where id =1;
SELECT *from test1
id | userid | mount |
---|---|---|
1 | 1 | 12 |
SELECT *from test1
id | userid | mount |
---|---|---|
1 | 1 | 1111 |
update test1 set amount= 12 where id =1;
commit;
SELECT *from test1
这时候事件A再去查询
SELECT *from test1
id | userid | mount |
---|---|---|
1 | 1 | 12 |
3.3 Repeatable read
更改事务
set session TRANSACTION ISOLATION LEVEL REPEATABLE READ;
START TRANSACTION
这时候我们事务B进行修改
UPDATE test1 set amount = 12 where id =1;
SELECT *from test1
id | userid | mount |
---|---|---|
1 | 1 | 12 |
SELECT *from test1
id | userid | mount |
---|---|---|
1 | 1 | 1111 |
这时候把事务B提交
commit;
SELECT *from test1
id | userid | mount |
---|---|---|
1 | 1 | 12 |
SELECT *from test1
id | userid | mount |
---|---|---|
1 | 1 | 1111 |
这时候我们在B事务插入一个数据并且提交事务查询
insert into test1 VALUES(4,4,4444);
commit;
SELECT *from test1
id | userid | mount |
---|---|---|
1 | 1 | 1111 |
2 | 2 | 2222 |
3 | 3 | 3333 |
4 | 4 | 4444 |
SELECT *from test1
id | userid | mount |
---|---|---|
1 | 1 | 1111 |
2 | 2 | 2222 |
3 | 3 | 3333 |
insert into test1 VALUES(4,4,4444);
会发现它报错了主键冲突因为我们id是主键,这时候就产生了幻读。设置Serializable就好了
3.4 Serializable
? 解决一切
3.5 对比
事务隔离级别 | 脏读 | 不可重复读 | 换读 |
---|---|---|---|
Read-uncommitted(读未提交) | 会 | 会 | 会 |
Read-committed(读取已提交) | 不会 | 会 | 会 |
Repeatable-read(可重复读) | 不会 | 不会 | 会 |
Serializable(串行化) | 不会 | 不会 | 不会 |
推荐阅读
- Mysql|Mysql连表查询JoinON详细笔记 作者:哇塞大嘴好帥
- Mysql|Mysql数据库常用类型 作者(哇塞大嘴好帥(哇塞大嘴好帅))
- sql|sql 获取两个月内数据_如何在3个月的时间内自学成为数据分析师()
- #springboot|springboot通过bean连接MySQL数据库
- CS246: Mining Massive Datasets
- 避免重复造轮子,Java 程序员必备
- C#数据库|C#实现学生信息管理系统---登录实现
- 编程语言|20天拿到美团快手小米搜狐跟谁学offer
- Java|面试官问(说说你对ZooKeeper集群与Leader选举的理解())