目录
事务
事务通常指一段SQl,要么都成功,要么都失败。但也可以手动commit失败的事物,使执行成功的部分SQL提交;
事务有四大特性 ACID,分别是原子性、一致性、隔离性和持久性。
事务的问题
多事务并发有三种异常情况,违反了隔离性:
- 脏读:读到了其他事务还没有提交的数据。
- 不可重复读:对某数据进行读取,发现两次读取的结果不同,也就是说没有读到相同的内容。这是因为有其他事务对这个数据同时进行了修改或删除。
- 幻读:事务 A 根据条件查询得到了 N 条数据,但此时事务 B 更改或者增加了 M 条符合事务 A 查询条件的数据,这样当事务 A 再次进行查询的时候发现会有 N+M 条数据,产生了幻读
不可重复读和幻读的区别
相同点
不可重复读 和 幻读都是在先后两次读取的时候发现不一致的情况
不同点
不可重复读是同一条记录的内容被修改了,重点在于UPDATE或DELETE
幻读是查询某一个范围的数据行变多了或者少了,重点在于INSERT
事务隔离级别
事务隔离级别用来解决以上三种情况,四种隔离级别从低到高分别是:
脏读 | 不可重复读 | 幻读 | 备注 | |
---|---|---|---|---|
读未提交(READ UNCOMMITTED ) | 允许 | 允许 | 允许 | 最低级别,不使用锁 |
读已提交(READ COMMITTED) | 禁止 | 允许 | 允许 | Oracle 和 SQL Server默认级别,可以在sql中加锁来避免不可重复读或者幻读 |
可重复读(REPEATABLE READ) | 禁止 | 禁止 | 允许 | MySQL 默认的隔离级别 |
可串行化(SERIALIZABLE) | 禁止 | 禁止 | 禁止 | 最高级别的隔离,牺牲了系统的并发性 |
查看隔离级别
SHOW VARIABLES LIKE 'transaction_isolation';
设置隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
总结
1、隔离级别越低,意味着系统吞吐量(并发程度)越大,但同时也意味着出现异常问题的可能性会更大。在实际使用过程中我们往往需要在性能和正确性上进行权衡和取舍,没有完美的解决方案,只有适合与否;
2、MySQL 默认是事务自动提交,这里我们还需要将 autocommit 参数设置为 0,(两个连续的事务,第二个Begin;执行时,第一个会被隐式提交/commit)
SET autocommit = 0;