一、事务
1、事务的应用场景
在实际开发过程中,如果操作转账,往往要多次访问数据库才能完成。转账是一个用户扣钱,另一个用户加钱。如果有其中一条 SQL 语句出现异常,这条SQL语句就可能执行失败。
事务执行是一个整体,所有的SQL语句都必须执行成功,如果有其中一条 SQL 语句出现异常,则所有的 SQL都要回滚,整个业务执行失败。
2、案例:模拟 加藤鹰 给 泷泽萝拉 转账500元
转账操作需要执行两条语句,则:
如果执行完第一条语句后,服务器崩溃了,那就造成了 加藤鹰的余额减少了500,而泷泽萝拉的余额并没有增加500。
只有当两条语句都执行成功的话,转账才算成功,这就用到了事务
3、手动提交事务
4、自动提交事务
二、事务的原理
1、事务开启之后,所有的操作都会临时保存到事务日志中,事务日志只有在得到 commit
命令后才会同步到数据表中,其他任何情况都会情况日志(rollback
断开连接)
2、原理图
3、事务的步骤
- 客户端连接数据库服务器,创建连接时创建此用户的临时日志文件
- 开启事务以后,所有的操作都会先写入到临时日志文件中
- 所有的查询操作都从表中查询,但会经过日志文件加工后才返回
- 如果事务提交则将日志文件中的数据写到表中,否则情况日志文件
三、事务的回滚点
1、回滚点
在某些成功的操作完成后,后续的操作又可能成功有可能失败,但是不管成功还是失败,前面的操作都已经成功,可以在当前成功的位置设置一个回滚点,可以供后续失败操作返回到该位置,而不是返回所有操作,这个点称为回滚点
2、回滚点的操作语句
3、回滚总结
设置回滚点可以让我们在失败的时候回到回滚点,而不是回到事务开启的时候
四、事务的隔离级别
单词
isolation
:隔离transaction
:交易、业务、事务level
:级别、数量
隔离级别的命令
- 查询隔离级别:
select @@tx_isolation;
- 设置全局隔离级别:
set global transaction isolation level 级别字符串;
- 设置当前隔离级别:
set session transaction isolation level 级别字符串;
1、脏读
以 account 表为例
A窗口开启事务,进行操作数据后,在没有提交事务的时候,B窗口是可以看到A操作的数据的。由此可见,脏读的隔离安全性最低。
解决脏读的问题:将全局隔离级别设置为:read committed
总结:read committed 的方式可以避免脏读的发生
2、不可重复读
在 B 窗口第二次查看数据发现与第一次查看的数据不同,对于B窗口来说,不知道那次的数据是正确的。
如果要解决这个问题,就要解决不可重复的问题
结论:同一个事务中,为了保证数据多次查询一致,必须使用 repeatable read
隔离级别
3、幻读
将事务的隔离级别设置到最高 serializable
来阻挡幻读的发生
- 当在A窗口
commit
提交事务后,B窗口才会执行插入 - 这时在A窗口执行
select count(*) from account;
发现数据没变,还是2 - 接着在B窗口执行
commit
提交事务后,在次A窗口执行select count(*) from account;
才能看到最新的数据,是3
总结:使用serializable
隔离级别时,一个事务没有执行完,其他事务的SQL语句执行不了
来源:CSDN
作者:CSDN-Lemon
链接:https://blog.csdn.net/weixin_43860260/article/details/96723151