dw怎么导入网站模板,小程序推广平台,记事本怎么做网站,wordpress如何自己添加锚文本目录 文章声明⭐⭐⭐让我们开始今天的学习吧#xff01;事务简介事务操作模拟转账操作开启事务提交事务回滚事务查看/设置事务提交方法实例演示 事务四大特性并发事务问题分类 事务隔离级别分类查看/设置事务隔离级别实例演示 文章声明⭐⭐⭐
该文章为我#xff08;有编程语… 目录 文章声明⭐⭐⭐让我们开始今天的学习吧事务简介事务操作模拟转账操作开启事务提交事务回滚事务查看/设置事务提交方法实例演示 事务四大特性并发事务问题分类 事务隔离级别分类查看/设置事务隔离级别实例演示 文章声明⭐⭐⭐
该文章为我有编程语言基础非编程小白的 MySQL复习笔记知识来源为 B站UP主黑马程序员的MySQL课程视频归纳为自己的语言与理解记录于此并加以实践此前我已经学习过了MySQL现在是在复习阶段所以不是面向小白的教学文章不出意外的话我大抵会 持续更新想要了解前端开发技术栈大致有Vue2/3、微信小程序、uniapp、HarmonyOS、NodeJS、Typescript与Python的小伙伴可以关注我谢谢大家 让我们开始今天的学习吧
事务简介
事务是一组操作的集合它是一个不可分割的工作单位事务会把所有的操作当成一个整体一起向系统提交或撤销操作请求这意味着这些操作要么同时成功要么同时失败
最常见的例子就是转账操作
要么成功转账A的余额-1000并且B的余额1000要么转账失败A和B的余额都不变和转帐前一致不允许出现A已经转账了1000但是由于网络问题或者系统问题B没有收到1000转账这就造成了数据库的数据错乱
MYSQL默认事务自动提交也就是说每当执行一条DML语句时MYSQL会隐式地提交事务 事务操作
模拟转账操作
模拟Richie转账1000给Taylor未出错正常情况操作示例如下
mysql select * from account where name Richie; # 首先查询Richhie账户余额是否足够1000
-------------------
| id | name | money |
-------------------
| 1 | Richie | 2000 |
-------------------
1 row in set (0.00 sec)mysql update account set money money - 1000 where name Richie; # 将Richie账户余额-1000
Query OK, 1 row affected (0.03 sec)
Rows matched: 1 Changed: 1 Warnings: 0mysql update account set money money 1000 where name Taylor; # 将Taylor账户余额1000
Query OK, 1 row affected (0.03 sec)
Rows matched: 1 Changed: 1 Warnings: 0mysql select * from account; # 可以看到数据没问题转账成功
-------------------
| id | name | money |
-------------------
| 1 | Richie | 1000 |
| 2 | Taylor | 3000 |
-------------------
2 rows in set (0.00 sec)模拟Richie转账1000给Taylor出错了操作示例如下
mysql select * from account;
-------------------
| id | name | money |
-------------------
| 1 | Richie | 2000 |
| 2 | Taylor | 2000 |
-------------------
2 rows in set (0.00 sec)mysql update account set money money - 1000 where name Richie; # 将Richie账户余额-1000
Query OK, 1 row affected (0.03 sec)
Rows matched: 1 Changed: 1 Warnings: 0mysql update account set money money 1000 where name Taylor # 这里我们模拟程序错误- 模拟出错。。。;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 模拟出错。。。 at line 2mysql select * from account; # 可以看到数据出现了错乱的现象Taylor并未收到1000转账
-------------------
| id | name | money |
-------------------
| 1 | Richie | 1000 |
| 2 | Taylor | 2000 |
-------------------
2 rows in set (0.00 sec)开启事务
开启事务这个操作只有在自动提交事务的情形下才能发挥作用
start transaction;
# 或者
begin;提交事务
commit;回滚事务
rollback;查看/设置事务提交方法
mysql # 查看事务提交方式
mysql select autocommit;
--------------
| autocommit |
--------------
| 1 |
--------------
1 row in set (0.03 sec)mysql # 关闭自动事务提交0关闭1开启
mysql set autocommit 0;
Query OK, 0 rows affected (0.03 sec)mysql # 开启自动事务提交0关闭1开启
mysql set autocommit 1;
Query OK, 0 rows affected (0.00 sec)实例演示
select 语句会自动提交一次事务
mysql # 关闭自动提交事务
mysql set autocommit 0;
Query OK, 0 rows affected (0.00 sec)mysql # 查看原始数据
mysql select * from account;
-------------------
| id | name | money |
-------------------
| 1 | Richie | 2000 |
| 2 | Taylor | 2000 |
-------------------
2 rows in set (0.00 sec)mysql # 更改数据
mysql update account set money money - 1000 where name Richie;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0mysql update account set money money 1000 where name Taylor;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0mysql # 再查看数据此时数据应该还是Richie2000Taylor2000只不过因为select语句会自动提交一次事务所以变成了正常提交过事务后的数据原表数据应该如下
-------------------
| id | name | money |
-------------------
| 1 | Richie | 2000 |
| 2 | Taylor | 2000 |
-------------------mysql select * from account; # select语句自动提交了一次事务数据变为如下
-------------------
| id | name | money |
-------------------
| 1 | Richie | 1000 |
| 2 | Taylor | 3000 |
-------------------
2 rows in set (0.00 sec)模拟出现错误时回滚事务
mysql select * from account; # 先查询原始数据
-------------------
| id | name | money |
-------------------
| 1 | Richie | 2000 |
| 2 | Taylor | 2000 |
-------------------
2 rows in set (0.00 sec)mysql update account set money money - 1000 where name Richie; # Richie转账1000
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0mysql update account set money money 1000 where name Taylor # 模拟错误- 模拟出现错误。。。;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 模拟出现错误。。。 at line 2
mysql rollback; # 回滚事务以至于上次提交事务之前的所有SQL语句都失效
Query OK, 0 rows affected (0.03 sec)mysql select * from account; # 再次查询会发现跟什么事都没发生一样
-------------------
| id | name | money |
-------------------
| 1 | Richie | 2000 |
| 2 | Taylor | 2000 |
-------------------
2 rows in set (0.00 sec)事务四大特性
原子性Atomicity事务是不可分割的最小操作单元要么全部成功要么全部失败一致性Consistency事务完成时必须使数据全部保持一致状态隔离性Isolation数据库系统提供的隔离机制保证事务在不受外部并发操作影响的独立环境下运行持久性Durability事务一旦提交或回滚它对数据库中的数据的改变就是永久的 并发事务问题
分类
问题描述脏读一个事务读到另一个事务还没有提交的数据不可重复读一个事务先后读取同一个记录但两次读取的数据不同称之为不可重复读幻读一个事务按照条件查询数据时没有对应的数据行但是在插入数据时又发现这行数据已经存在好像出现了一个幻影 事务隔离级别
分类
√表示会出现这种情况 ❌表示不会出现这种情况
隔离级别脏读不可重复读幻读read uncommitted√√√read committedOracle默认❌√√repeatable readMySQL默认❌❌√serializable串行化❌❌❌
事务隔离级别越高数据越安全但是性能就越低
查看/设置事务隔离级别
session指的是更改当前会话的事务隔离级别global指的是更改全局的事务隔离级别
# 查看事务隔离级别
select transaction_isolation;
# 设置事务隔离级别session指的是更改当前会话的事务隔离级别global指的是更改全局的事务隔离级别
set [session | global] transaction isolation level {read uncommitted | read committed |repeatable read | serializable};实例演示
这里因为验证的流程比较复杂大家可以自行尝试验证
大家可以开启两个终端打开登录mysql从而来模拟两个主机对数据库同时进行操作