SQL:事务
1. 基本介绍
- 概念:
一个包含多个操作的业务,如果在执行过程中出现错误,可能会因为执行了错误前的操作无法执行错误后的操作导致数据异常。这就需要将业务委托给事务,事务会对整个操作进行判断。如果所有操作都顺利进行,就提交这些操作,给出成功信息;如果操作过程中出现了错误,就将错误之前的操作进行回滚,回滚到业务的开始,提示业务出现错误。有效的保证了数据的正确性有效性。
其实事务并不是一个实体,而是一种概念。它将数据库的操作和结果存放在临时的空间,并没有真正的对数据库中的数据进行操作。如果整套业务完成没有出错,事务就将临时空间中的操作和结果在数据库中执行;如果出现了错误,就执行回滚操作,说是回滚,其实就是清空临时空间,也就回到了开启事务时的状态。 - 事务的操作
- 开启事务:
START TRANSACTION;
- 回滚事务:
ROLLBACK;
- 提交事务:
COMMIT;
- 注意
在 MySQL 数据库中,事务是默认自动提交的。每执行一条DML语句,就会提交一次事务。开启手动事务管理以后,只要不手动提交事务,任何DML语句操作都不会真正的实现在数据库中。
- 开启事务:
2. 事务的默认提交方式
- 查询
SELECT @@autocommit;
解释:值为"1"的时候是自动提交事务;值为"0"的时候是手动提交事务。 - 修改
SET @@autocommit = 0;
注意:此时如果在执行了DML语句后不执行 COMMIT 提交事务,数据库的数据不会改变。
3. 事务的特征
原子性
- 事务是不可分割的最小单位,要么全部成功,要么全部失败回滚。
- 当事务提交或回滚后,数据库会永久的保存当前数据。
- 多个事务之间互不产生影响,各自独立。
- 数据操作的前后,数据总量不变。
4. 事务的隔离级别
- 问题描述
理想的情况下,事务与事务之间是隔离的,互相独立互不影响。但是一旦多个事务操作同一批数据,则会产生错误。故需要给不同的事务设定不同的隔离级别,就可以解决错误。- 脏读:事务读取了另一个事务还未提交的数据,根据脏数据进行的操作是错误的。
- 不可重复读:由于两次查询中间另外一个事务提交了 "修改操作",事务发现两次读取的数据内容不一致。
- 幻读:事务对所有数据进行操作的时候,另一个事务提交了 "插入或者删除操作" 后,第一个事务发现两次读取的数据数量不一样,就像是没有执行过操作一样。
- 隔离级别
隔离级别从 read uncommitted 到 serializable ,安全等级越来越高,但是效率越来越低。选择合适的隔离级别,在效率和安全方面做最佳平衡。MySQL的默认隔离级别是 repeatable read ;Oracle数据库默认隔离级别是 read committed。- read uncommitted:读未提交
问题:脏读、不可重复读、幻读 - read committed:读已提交
问题:不可重复读、幻读 - repeatable read:可重复读
问题:幻读 - serializable:串行化
问题:效率低
- read uncommitted:读未提交
5. 隔离级别的操作
- 查询隔离级别:
SELECT @@tx_isolation;
- 设置隔离级别:
SET GLOBAL TRANSACTION ISOLATION <级别>;
重新登陆数据库后,隔离级别才生效。