数据库事务隔离级别

1)事务的ACID特性

原子性:将事务看作一个原子操作,是不可分割的。如果在事务执行过程中发生了错误,会执行回滚操作。

一致性:事务执行前后,数据库的完整性保持一致。例如:A给B转账,B的余额增加,A的余额不能还保持原样。

隔离性:事务对于在同一时间对同一数据的操作是相互隔离的,不能互相干扰。

持久性:当事务完成后,需持久化到数据库,无法再进行回滚操作。

2)并发事务导致的问题

脏读:事务A更新数据,但未提交,事务B恰好对这块数据进行读取,然后A进行了回滚,那么B就读到了脏数据。

不可重复读:事务A多次读取某部分数据 ,在这个过程中事务B对数据进行了修改并提交,导致事务A多次读取到的数据不一致

幻读:和不可重复读类似,幻读指的是事务A多次读取数据,事务B在这个过程中执行了新增或者删除操作,导致A读取到的行数和原来不一致。

所以解决不可重复读的问题,需要加行级锁,解决幻读问题需要加表级锁

3)数据库的事务隔离级别
脏读不可重复读幻读
读未提交 READ UNCOMMITTED存在存在存在
读提交 READ COMMITTED不存在存在存在
可重复读 REPEATABLE READ不存在不存在存在
串行化 SERIALIZABLE不存在不存在不存在
4)MySQL的事务隔离级别

MySQL的默认事务隔离级别为可重复读,但是MySQL 的可重复读隔离级别解决了幻读问题

MySQL如何解决幻读?

MySQL使用行锁+间隙锁来解决幻读问题,二者合一的锁叫做NEXT-KEY锁。

行锁:

事务A对某条数据执行update操作,在操作的时候会对要修改的行加行锁,直到事务提交后才释放锁。如果事务B申请行锁的时候,发现锁已被占用,那么事务B就会处于等待状态,直到锁被释放。

加行锁的时候分为有索引和无索引两种情况:

update emp set name = ‘张三’ where id = 1

这条语句中的查询条件是主键,也就是有索引的情况,这种情况会直接找到id=1的那条数据并加锁

update emp set name = ‘张三’ where age = 20

假设emp表没有在age字段上加索引,那么在执行更新操作的时候首先会对所有行加上锁,然后按照条件进行过滤,不符合条件的释放锁。

间隙锁:

假设:emp表中有两条数据,age字段分别为20 30 ,并且在age字段上添加了索引。

那么现在就有了以下几个区间:

(-∞, 20]、(20, 30]、(30, +∞)

当执行insert语句的时候,按照区间来加间隙锁,

例如我们插入一条age=20的数据,这一行会加上行锁,并且在(-∞, 20]、(20, 30]这两个区间也加上了间隙锁,当有新的数据要插入这个区间的时候就会发生锁等待。

如果没有索引,那么在加锁的时候会给整张表加间隙锁,所有插入操作均需等待锁释放。

相关SQL语句

查询语句:SELECT @@tx_isolation;

设置隔离级别:set [作用域] transaction isolation level [事务隔离级别]

作用域可以是:session或者global,session针对当前会话,global代表全局

例如:set global transaction isolation level read committed;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值