事务概述
所谓事务:就是事务正对数据库的一组操作(就是由一条或多条SQL语句组成进行管控。如果任一条语句无法执行,那么所有的语句都不会执行。也就是说,事务中的语句要么都执行,要么都不执行)。
start transaction;# 开启事务
#sql...
commit;# 事务提交
rollback;# 事务回滚
事务开启后,执行SQL语句
SQL语句执行成功或,提交事务
不想执行事务,取消事务(事务回滚)
注意:
- 平常书写的SQL语句都是自动提交的它,会立即失效;开启事务的语句,需要使用commit,手动提交,否则不会失效。
- rollback,只能针对未提交的事务执行回滚操作,已提交的事务不能回滚。
事务的特性
事务必须同时满足4个特性,简称ACID标准。即
- 原子性(Atomicity)
- 一致性(Consistency)
- 隔离性(Isolation)
- 持久性(Durability)
原子性
- 事务必须被视为 一个不可分割的最小工作单元。
- 只有事务中 所有的 数据库操作 都执行成功才算整个事务执行成功。
- 若有一个SQL语句失败,则已经执行成功的SQL语句必须撤销,数据库状态回到退回执行事务前的状态。
一致性
- 数据库执行前状态 保持一致
- 数据库执行后状态 保持一致
- 事务中间的处理不管如何,事务结束整个数据库的状态是一致的
隔离性
- 一个用户开启的(一个)事务 不能被 其他事务的操作所干扰。
- 多个并发事务 要相互隔离
持久性
- 事务一旦commit,其做的操作 就会永久保存在数据库中
- 即使数据库发生故障 应该不会造成影响,或者说影响很小。
- 事务的持久性,只不能做到100%的持久,只能从事务本身的角度来保证永久性,一些外部原因导致数据库发生故障,如硬盘故障损坏,那么所提交的数据可能都会丢失。
事务的隔离级别
隔离级别的产生
通常情况下,数据库是多线程并发访问的,所以容易出现多个线程同时开启事务的情况。在该情况下和可能可能出现脏读,重复读及幻读的情况,为了避免这种情况下的发生,就需要为事务设置隔离级别。
read uncommitted
READ UNCOMMITTED(读取未提交),事务中最低级别。
在该级别下的事务,可以读取另一个事务中为为提交的数据,而这个数据也 就是脏数据,这样的读取方式也称为脏读(dirty read).级别太低,所以用的很少。
read committed
为了避免脏读的发生,使用 read committed。
# 设置隔离级别
set session transaction isolation level read committed;
# 查询事务隔离级别
select @@tx_isolation;
多数 数据库管理系统的默认隔离级别都是:read committed。例如:Oracle
在该级别下,事务只能读取 其他事务已经提交的内容,可以避免脏读但是不能避免重复读和幻读的情况。
重复读
重复读:就是在一个事务内 重复读取 别的线程已经提交的数据时 读取的结果不一致。
原因:查询的过程中其他事务做了更新操作
幻读
幻读:在一个事务内两次查询中 数据条数不一致。导致该问题的**原因:**是查询的过程中其他的事务做了添加操作。
repeatable read
REPEATABLE READ(可重复读)是MYSQL的驶入隔离级别。
它可以避免和不可重复读。但理论上,该级别会出现幻读的情况
MySQL的存储引擎通过多版本并发控制机制解决了该问题,因此该级别是可以避免幻读的。
不可重复读
不可重复读:指一个事务中两次查询的结果不一致,原因在查询的过程从中其他事务做了更新操作。
不可重复读和脏读类似,但是脏读是:读取其他线程的事务未提交的脏数据;而不可重复读:是在该事务内重复读取其他线程已提交的数据但数据并不一致的情况
幻读
幻读(PHANTOM READ)又被称为虚读,是指一个事务内两次查询中数据条数不一致。这不是一种错误。
serializable
SERIALIZABLE(可串行化)是事务的最高隔离级别,它会强制对事务进行排序,使之不会发生冲突,从而解决脏读,幻读,重复读的问题。但是,该级别可能导致大量的超时现象和锁竞争,实际应用中很少使用。