💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
>[info]事务,是现实生活中的一组逻辑操作单元,这组操作要么全部成功,要么全部失败 例子:转账 张三-500元 李四+500元 **事务的特性(ACID)** - 原子性(automicity):事务不可再分割,要么全执行,要么全不执行。实现主要基于undo log(回滚日志文件) - 一致性(consistency):执行事务会是数据从一个一致状态切换到另一个一致状态 - 隔离性(isolation):事务执行不受其他事务的干扰。实现主要基于锁机制、数据的隐藏列、undo log和类next-key lock机制 - 持久性(durability):事务一旦提交,将永久改变数据库数据。实现主要基于redo log(重做日志文件) 两个并发事务一定会出现“脏读”,即读到的数据不准确 <br/> ## 6.1 脏读、不可重复读和幻读 首先来看并发情况下,读操作可能存在的三类问题: - (1)脏读:当前事务(A)中可以读到其他事务(B)未提交的数据(脏数据),这种现象是脏读。 举例如下(以账户余额表为例): ``` 事务A和B在T1时刻同时开启事务; 事务B在T2时修改“张三”余额由100变为200; 事务A在T3时查询“张三”的余额,结果为200【脏读】(因为事务B还没有提交事务) 事务B在T4时提交事务 ``` - (2)不可重复读:在事务A中先后两次读取同一个数据,两次读取的结果不一样, 这种现象称为不可重复读。脏读与不可重复读的区别在于:前者读到的是其他事务未提交的数据, 后者读到的是其他事务已提交的数据。举例如下: ``` 事务A和B在T1时刻同时开启事务; 事务A在T2时查询“张三”的余额,结果为100修改“张三”余额由100变为200; 事务B在T3时修改“张三”余额由100变为200; 事务B在T4时提交事务 事务A在T5时查询“张三”的余额,结果为200【不可重复读】(两次读到的数据不一样) ``` - (3)幻读:在事务A中按照某个条件先后两次查询数据库,两次查询结果的条数不同, 这种现象称为幻读。不可重复读与幻读的区别可以通俗的理解为:前者是数据变了, 后者是数据的行数变了。举例如下: ``` 事务A和B在T1时刻同时开启事务; 事务A在T2时查询0<id<5的所有用户的余额,结果只查到“张三:100(id=1)”; 事务B在T3时向余额表中插入新用户:李四:200(id=2); 事务B在T4时提交事务; 事务A在T5时再次查询0<id<5的所有用户的余额,结果查到“张三:100(id=1) 李四:200(id=2)“【幻读】(不应该查到李四) ``` <br> ## 6.2 事务的创建 >隐式事务:事务没有明显的开启和结束的标记 比如insert、update、delete语句,会自动开启事务 delete from 表 where id =1; > 显式事务:事务具有明显的开启和结束的标记 > 前提:必须先设置自动提交功能为禁用 > 在自动提交模式下,如果没有 start transaction 显式地开始一个事务, > 那么每个 sql 语句都会被当做一个事务执行提交操作。 (1). 开启事务 ``` set autocommit=0; start transaction;(可选) ``` (2).编写事务的sql语句 (3).结束事务 ``` commit; rollback; ``` >[success]mysql 的默认隔离级别为:repeatable read 可重复读 Oracle的默认隔离级别为:read committed 读 已提交 隔离级别(isolation) | | 脏读 | 不可重复读 | 幻读 | 第一类丢失更新 | 第二类丢失更新 | :-- | :-: | :-: | :-: | :-: | :-: | | read uncommitted | √ | √ | √ | × | √ | | read committed | × | √ | √ | × | √ | | repeatable eead | × | × | √ | × | × | | serializable | × | × | ×| × | × | 查看隔离级别 `select @@tx_isolation;(以后看到tx,要知道它表示事务的意思) ` 设置隔离级别 ``` set session|global transaction isolation level 隔离级别; session 会话,表示设置的隔离级别只在当前会话中有效; global 全局,表示设置的隔离级别在所有的会话中都有效(但是其他需要重启一次会话,不然其他的会话加载的内容会是设置全局级别之前的内容) ``` 比如:打开浏览器输入百度,就表示 你与浏览器开始了一个会话,关闭窗口就结束本次会话。 再比如,你打开cmd,输入命令,就表示开启了与命令行的会话 <br> 数据库引擎: **MyISAM引擎**,不支持事务;只支持表锁。 **innoDB引擎**支持事务,也支持表锁和行锁 >行锁:当两个不同事务操作同一个数据(并发执行),前一个事务还没有结束事务(提交或回滚),后一个事务就无法执行操作(会陷入等待状态) >表锁:与行锁功能相同,但是不限于当前行的数据,而是整个表的其他数据都不能修改(除非当前事务结束) 行锁开销大,粒度小,并发性好;表锁开销小,粒度大,并发性差