事务acid,隔离级别,锁

事务:一个或一组SQL语句组成的一个执行单元,这个单元要么全执行,要么全不执行。是相互依赖的,其中某行语句发生失败或者错误,整个单元将会回滚。

事务ACID

原子性  Atomicity:不可分割,要么全部成功,全部失败

快照

mvcc 多版本并发过程

一致性 Consistency:事务的执行结果必须使数据库从一个一致性状态到另一个一致性状态。前后状态一致。

比如:转账前后 两个账户的总金额保持不变

数据库本身的约束 一致性读 一致性写

一致性是事务最终的根本追求,通过原子性,隔离性,持久性 保证一致性的实现

隔离性 Isolation:并发执行的事务不会相互影响 ,其对数据库的影响和它们串行执行时一样。

即要达到这么一种效果:对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执行。

共享锁 拍他所 独占锁 临键锁 间隙锁 自增锁 意向锁

读未提交 读已提交 可重复度 串行化

持久性Durability: 事务一旦提交,其对数据库的更新是持久的。任何事务或系统故障都不会导致数据丢失。数据持久化

wal日志 write ahead log 预写日志

事务的隔离性由锁机制实现,事务的原子性,持久性,一致性由事务的redo日志和undo日志来实现

 

原子性实现原理

日志 undo、redo   归属于innodb引擎    bin log 归属mysql sever  

myisam 不支持事务,没有undo、 redo日志

undo log 事务回滚

逻辑日志 当delete一条记录时,undolog会记录一条insert 记录,当insert delete 当update 记录相反的update sql语句

逻辑日志 对当前sql记录,不改当前物理页的内容

物理日志

mvcc  multipart version conccurry controll  undolog 记录了当前数据之前的历史版本

MVCC只在Read CommittedRepeatable Read下会开启。但是在这两种隔离级别下对于快照指定的数据定义不同。

Read Committed下,MVCC读取的是被锁定数据的最新的一份数据
Repeatable Read下,MVCC读取的是事务刚开始时候的数据

持久性实现原理

redo log  记录的是新数据的备份

在事务提交前,只要将redo log 持久化即可,不需要将数据持久化

user space 当前进程内存空间    innodeb engine> log buffer  >redo log buffer undo log buffeg

kernel space 系统内存空间   os buffer

fsync ->  磁盘 redo log file ib_logfilen \undo log file  零拷贝

所以mysql是否持久化的关键要看redo log的持久化策略,mysql提供了三种redo log持久化策略

  • 0:只写redo log,每秒落地一次,性能最高,数据一致性最差,如果mysql奔溃可能丢失一秒的数据
  • 1:写redolog buffer同时落地,性能最差,一致性最高
  • 2:写redo log buffer同时写入到os buffer,性能好,安全性也高,只要os不宕机就能保证数据一致性

  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qPkgwBV2-1573913769601)(media/15738994378780/15739110116354.jpg)]

 

数据更新流程:

先查询数据 再更新

获取数据

数据页是否在内存中  否从磁盘加载数据  是 返回数据

更改数据

写入新的数据

新数据更新到内存

写入redo,始于prepare 阶段

写binlog

提交事务,处于commit阶段

 

mysql 隔离级别   隔离级别越高,越安全,性能越低

读未提交                                         脏读 不可重复读 幻读

读已提交    orecal 默认隔离级别    不可重复读  幻读

rc读的最新的快照

可重复读    mysql默认隔离级别     幻读    

RR 读的是历史

串行化

 

脏读:A,B两事务,A事务会读取到B事务未提交的数据,然后B因为某些原因回滚数据,所以A就读取了B没有提交的数据,也称脏数据。

不可重复读:同一个事务,相同的sql语句,不同的结果

幻读:类似于不可重复读,都是在一个事务周期内读的数据不一致,

幻读和不可重复读 区别在于幻读是侧重于插入操作带来的影响,而不可重复读是编辑或者删除带来的影响

 

为什么阻止幻读的隔离级别比不可重复读的高?

  • 因为innodb是行级锁,不可重复读是针对正在修改或删除的数据行加锁,但是并不是表锁,我还可以对这个表进行插入操作,所以会出现幻读

 

 

行锁 

记录锁,间隙锁,临键锁都属于行锁

记录锁

间隙锁:

临键锁

 

共享锁

    共享锁又称为读锁,简称S锁,顾名思义,共享锁就是多个事务对于同一数据可以共享一把锁,都能访问到最新数据。

  1. 多个事务的查询语句可以共用一把共享锁;
  2. 如果只有一个事务拿到了共享锁,则该事务可以对数据进行 UPDATE DETELE 等操作;
  3. 如果有多个事务拿到了共享锁,则所有事务都不能对数据进行 UPDATE DETELE 等操作。

 

lock in share mode

排他锁

      排他锁又称为写锁,简称X锁,顾名思义,排它锁不能与其它锁并存,而且只有一个事务能拿到某一数据行的排它锁,其余事务不能再获取该数据行的所有锁。

  1. 只有一个事务能获取该数据的排它锁;
  2. 一旦有一个事务获取了该数据的排它锁之后,其余事务对于该数据的操作将会被阻塞,直至锁释放。

for update

独占锁

自增锁  

意向锁  

InnoDB允许表锁和行锁同时存在。
但是,假如表锁覆盖了行锁的数据,所以表锁和行锁也会产生冲突。为了解决这种表锁和行锁共存的问题

 

 innodb 只有通过索引条件检索数据,innodb才使用行级锁,否则,innodb将使用表锁

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值