Skip to content

Commit c098db4

Browse files
committed
learn MySQL‘s 事务
1 parent a4a7777 commit c098db4

12 files changed

Lines changed: 208 additions & 3 deletions

DataBase/MySQL/1-MySQL-Basic.md

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -846,6 +846,17 @@ select * from emp where (salary,managerid) = (
846846

847847
示例如下:
848848

849+
```mysql
850+
-- 查询与鹿杖客、宋远桥的职位及薪资相同的员工信息
851+
select * from emp where (job,salary) in (
852+
select job,salary from emp where name in ('鹿杖客','宋远桥')
853+
);
854+
855+
-- 查询入职日期是2006-01-01之后的员工信息及其部门信息
856+
select * from (select * from emp where entrydate>'2006-01-01') temp
857+
left join dept on temp.dept_id=dept.id;
858+
```
859+
849860

850861

851862
---
@@ -856,11 +867,162 @@ select * from emp where (salary,managerid) = (
856867

857868
## 六、事务
858869

870+
### 1.概述
871+
872+
事务是一组操作的集合,它是一个不可分割的工作单位。事务会把所有操作作为一个整体一起向系统提交或撤销操作,这意味着这些操作要么同时成功,要么同时失败。
873+
874+
比如对于转账操作,我们就需要通过事务来保障它的安全性:在业务逻辑执行之前开启事务,执行完毕后提交事务。如果执行过程中报错,则回滚事务,把数据恢复到事务开始之前的状态。
875+
876+
![image-20251229214947783](images/image-20251229214947783.png)
877+
878+
**注意**:MySQL的事务默认是自动提交的,也就是说,当执行完一条DML语句时,MySQL会立即隐
879+
880+
式地提交事务。
881+
882+
883+
884+
---
885+
886+
887+
888+
### 2.事务操作
889+
890+
#### 2.0 数据准备
891+
892+
```mysql
893+
create table account(
894+
id int primary key AUTO_INCREMENT comment 'ID',
895+
name varchar(10) comment '姓名',
896+
money double(10,2) comment '余额'
897+
) comment '账户表';
898+
insert into account(name, money) VALUES ('张三',2000), ('李四',2000);
899+
```
900+
901+
902+
903+
#### 2.1 未开启事务
904+
905+
##### P1 正常情况
906+
907+
```mysql
908+
-- 转账操作:张三给李四转账1000
909+
-- 1.查询张三账户余额
910+
select money from account where name='张三';
911+
-- 2.如果张三余额大于1000,则将张三余额-1000
912+
update account set money=money-1000 where name='张三' and money>1000;
913+
-- 3.将李四余额+1000
914+
update account set money=money+1000 where name='李四';
915+
```
916+
917+
运行以上三行代码后查看`account`表,可以看到转账成功:
918+
919+
![image-20251229220642512](images/image-20251229220642512.png)
920+
921+
##### P2 异常情况
922+
923+
```mysql
924+
select money from account where name='张三';
925+
update account set money=money-1000 where name='张三' and money>1000;
926+
模拟程序出现异常
927+
update account set money=money+1000 where name='李四';
928+
```
929+
930+
我们把张三和李四的余额都恢复到2000,运行以上三代码后查看`account`表,可以发现转账失败,张三余额减少1000,李四余额却没有增加,这是一个巨大的安全漏洞:
931+
932+
![image-20251229220949920](images/image-20251229220949920.png)
859933

860934

861935

936+
#### 2.2 开启事务
862937

938+
##### P1 方法一
863939

940+
```mysql
941+
-- 查看事务提交方式,设置为手动提交事务
942+
-- 这样我们执行的DML语句都不会提交, 需要手动的执行commit进行提交
943+
select @@autocommit;
944+
set @@autocommit=0;
945+
/*
946+
此处是业务逻辑代码
947+
*/
948+
-- 执行以上代码,若正常则提交事务
949+
commit;
950+
-- 执行以上代码,若出现异常则回滚事务
951+
rollback;
952+
```
953+
954+
##### P2 方法二
955+
956+
```mysql
957+
-- 开启事务
958+
start transactionbegin;
959+
/*
960+
此处是业务逻辑代码
961+
*/
962+
-- 执行以上代码,若正常则提交事务
963+
commit;
964+
-- 执行以上代码,若出现异常则回滚事务
965+
rollback;
966+
```
967+
968+
969+
970+
---
971+
972+
973+
974+
### 3.事务的四大特性ACID
975+
976+
+ **原子性(Atomicity)**:事务是不可分割的最小操作单元,要么全部成功,要么全部失败。
977+
+ **一致性(Consitency)**:事务完成时,必须使所有的数据都保持一致状态。
978+
+ **隔离性(Isolation)**:数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行。
979+
+ **持久性(Durability)**:事务一旦提交或回滚,它对数据库中的数据的改变就是永久的。
980+
981+
982+
983+
### 4.并发事务的三大问题
984+
985+
#### 4.1 脏读
986+
987+
**定义**:一个事务读到另一个事务还未提交的记录。
988+
989+
![image-20251229223539672](images/image-20251229223539672.png)
990+
991+
#### 4.2 不可重复读
992+
993+
**定义**:一个事务先后读取同一条记录,但两次读取到的记录内容不同。
994+
995+
![image-20251229223640756](images/image-20251229223640756.png)
996+
997+
#### 4.3 幻读
998+
999+
**定义**:一个事务按照条件查询记录时,没有对应的记录行,但是在插入记录时又发现这行记录已经存在,好像出现了“幻觉”。
1000+
1001+
![image-20251229224128202](images/image-20251229224128202.png)
1002+
1003+
1004+
1005+
### 5.事务隔离级别
1006+
1007+
#### 5.1 事务隔离级别
1008+
1009+
| 隔离级别 | 是否可能脏读 | 是否可能不可重复读 | 是否可能幻读 |
1010+
| :---------------------: | :----------: | :----------------: | :----------: |
1011+
| Read Uncommitted ||||
1012+
| Read Committed | × |||
1013+
| Repeatable Read(默认) | × | × ||
1014+
| Serializable | × | × | × |
1015+
1016+
隔离级别越高,数据越安全,但SQL性能越差。
1017+
1018+
#### 5.2 语法
1019+
1020+
```mysql
1021+
-- 查看事务隔离级别
1022+
select @@transaction_isolation;
1023+
-- 设置事务隔离级别
1024+
set session/global transaction isolation level 事务隔离级别;
1025+
```
8641026

8651027

8661028

DataBase/MySQL/1-MySQL-Basic.pdf

324 KB
Binary file not shown.
24.8 KB
Loading
6.51 KB
Loading
6.35 KB
Loading
26 KB
Loading
57 KB
Loading
60.4 KB
Loading
62.7 KB
Loading
75.5 KB
Loading

0 commit comments

Comments
 (0)