MySQL事务隔离级别
一、事务的基本要素(ACID)
原子性
(Atomicity
):事务中的所有操作,要么都成功,要么都失败,是一个不可再分的基本单位。一致性
(Consistency
):事务操作的结果,必须使数据库从原先的一致状态转换为另一个一致状态,即数据库的完整性约束没有被破坏 。隔离性
(Isolation
):不同事务之间的互不干扰。持久性
(Durability
):事务一旦提交,那么对数据库中的数据的改变是永久的。
二、事务并发产生的问题
1. 脏读
事务A读取了事务B更新的数据,然后事务B回滚操作,导致事务A读取的数据为脏数据。
2. 不可重复读
事务A读取了某一个数据,然后事务B在事务A多次读取该数据时,更新了该数据,导致事务A前后两次读取到的数据不一致,称为不可重复读。
3.幻读
事务A读取了某些符合条件的数据,然后事务B往数据库中插入了一条符合该条件的新数据,导致事务A再次查询时,多了一条符合该条件的数据,就好像发生了幻觉一样,称为幻读。
注意:不可重复读和幻读很容易混淆,不可重复读侧重于 修改,幻读侧重于 新增或删除 。解决不可重复读的问题只需要 锁住满足条件的行,而解决幻读需要 锁表 。
三、MySQL的事务隔离级别
事务隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交(read-uncommitted ) | 是 | 是 | 是 |
读已提交(read-committed ) | 否 | 是 | 是 |
可重复读(repeatable-read ) | 否 | 否 | 是 |
串行化(serializable ) | 否 | 否 | 否 |
MySQL
的默认事务隔离级别是可重复读(repeatable-read),它可以解决脏读和不可重复读问题。串行化事务隔离级别虽然能够解决脏读、不可重复读、幻读,但是它需要锁住整张表,效率很低。
补充:
数据库的隔离级别越高,就越能够保证数据的完整性和一致性,但是对并发性能的影响也越大。对于多数应用程序,可以优先考虑将数据库系统的隔离级别设置为
读已提交(Read Committed)
,它能够避免脏读,而且具有较好的并发性能。尽管它会导致不可重复读、幻读这些并发问题,但在可能出现这类问题的个别场合,可以通过采用悲观锁或乐观锁来解决。
四、MySQL事务常用命令
1. 查询隔离级别
# 查询事务隔离级别
select @@transaction_isolation;
+-------------------------+
| @@transaction_isolation |
+-------------------------+
| REPEATABLE-READ |
+-------------------------+
2. 设置会话的事务隔离级别
# 设置会话的事务隔离级别为读未提交
set session transaction isolation level read uncommitted;
3. 设置数据库的事务隔离级别
# 设置数据库事务隔离级别为读已提交
set global transaction isolation level read committed;
4. 事务操作
# 开启事务
start transaction;
# 提交事务
commit;
# 事务回滚
rollback;