数据库隔离机制

事务并发导致的五类数据丢失问题

事务并发:一个数据库同时运行多个事务

事务并发问题:并发事务同时访问或修改相同的数据记录

  • 第一类丢失更新【事务回滚丢失数据:事务读取了相同数据,B事务提交了,A事务却回滚了】
  • 第二类丢失更新【覆盖丢失或两次更新:事务读取了相同数据,A事务修改提交后B事务修改提交,B覆盖了A事务提交的数据】
  • 脏读【读取了未提交的数据:A事务读取了并修改了某数据,但未提交,B事务使用该数据,该数据就是脏数据】
  • 不可重复读 同一事务,前后两次读取同一行数据,数据前后不一致
  • 幻读 同一事务,前后两次查询的数据记录数不一致

数据库隔离级别

隔离机制:为解决事务并发问题,必须引入有效的隔离机制,而隔离机制必须通过锁来实现

数据库事务的隔离级别有4个,由低到高依次为Read uncommitted、Read committed、Repeatable read、Serializable,这四个级别可以逐个解决脏读、不可重复读、幻读这几类问题。越高的隔离级别,能解决的数据一致性问题越多,理论上性能损耗更大,可并发性越低

脏读不可重复读幻读
Read uncommitted【读未提交】
Read committed【读已提交】解决
Repeatable read【不可重复读】解决解决
Serializable【序列化】解决解决解决
  • Oracle、SQL Server默认都会使用读提交(Read-Comitted)作为默认隔离级别

  • Mysql默认的隔离级别:Repeatable Read,但没有解决幻读问题,也没解决第二类丢失更新

  • 第二类丢失更新的解决方案:加悲观锁或乐观锁,通过代码解决

  • 隔离级别在读写数据时会锁住整张表,虽然解决了并发问题,但性能最差

当同个事务同时更新一条数据时,A事务先更新完成且未提交,B事务此时更新会出现锁等待超时的问题,mysql默认锁等待时间为50s

SHOW GLOBAL VARIABLES LIKE '%lock%'

对于InnoDB存储引擎,有三个隐藏列row_id【行id】、trx_id【事务id】、roll_pointer【回滚指针】,
row_id并不是必要的,有主键或者非NULL唯一索引时都不会包含row_id列

  • trx_id:每次对某条记录进行改动时,都会把对应的事务id赋值给trx_id隐藏列

  • roll_pointer:每次对某条记录进行改动时,都会把旧的版本写入到undo日志中,roll_pointer存放的指针可以到undo日志中找到记录修改前的信息

  • 每次对记录进行改动,都会记录一条undo日志,每条undo日志也都有一个roll_pointer属性

  • read view https://blog.csdn.net/qq_38538733/article/details/88902979

  • MVCC(Multi-Version Concurrency Control ,多版本并发控制)主要在Mysql的读已提交、可重复读隔离级别起作用

undo log日志【回滚日志】用于事务回滚,存放数据修改被修改前的值
redo log日志【重做日志】用于记录数据修改后的记录

当数据库对数据做修改的时候,需要把数据页从磁盘读到buffer pool中,然后在buffer pool中进行修改,那么这个时候buffer pool中的数据页就与磁盘上的数据页内容不一致,称buffer pool的数据页为dirty page 脏数据,如果这个时候发生非正常的DB服务重启,那么这些数据还没在内存,并没有同步到磁盘文件中(注意,同步到磁盘文件是个随机IO),也就是会发生数据丢失,如果这个时候,能够在有一个文件,当buffer pool 中的data page变更结束后,把相应修改记录记录到这个文件(注意,记录日志是顺序IO),那么当DB服务发生crash的情况,恢复DB的时候,也可以根据这个文件的记录内容,重新应用到磁盘文件,数据保持一致。

#查询隔离级别
SELECT @@TRANSACTION_ISOLATION;

#设置隔离级别
set tx_isolation='read-uncommitted';
set tx_isolation='read-committed';
set tx_isolation='repeatable-read';
set tx_isolation='serializable';
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值