@@ -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 transaction 或begin ;
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
0 commit comments