事务不是与当前连接无关联就是已完成_mysql索引锁事务

一 B+树逻辑特征:

1)m阶b+树要求每个节点最多有m个子节点

2)有k个子节点的非叶子节点拥有k-1个键,键按照升序排列

3)所有节点key从小多大排序,子节点之间指针关联,子节点都子同一层

4)所有的上一出层节点元素都同时存在于子节点,在子节点元素中是最大(或最小)元素

5)方便范围 主键查询

6)方便排序和分页

d37b242b2508010ee5dfcea866721174.png

B+结构体

class Node {//非叶节点Node parent;Node[] childs;Object[] keys;}class LeafNode {//叶节点Node parent; Object values[]; LeafNode left; LeafNode right;}

二 B+树 聚集索引

1)数据库不是一条条读写,innodb最小的存储单元是页(page)是按页读取,一页16k大小

2)除了最低层页存储了记录外,其他层存储的是key值,数据页与页之间链表关联

3)查询从根节点查询,根据key找到对于的页,找到数据页,在已经排好序的页内部查询,

树的高度2到3层,最多3次查询页数据就查询出来记录

4)每个表都有一个聚集索引,索引就是数据,数据就是索引

25ce7dd8df0c79e9a3ccc9204f9fd587.png

三 B+树辅助索引

1)辅助索引和聚集索引结构类似,区别在于辅助索引的叶子节点的页不存储数据行,而是存的主键值,所以在辅助索引查询时,会查询2课B+树,先从辅助索引查询主键,在从聚集索引查询最终的记录。

b3f78763664160cc40a294b20af57429.png

四 数据库的锁

按照锁的粒度可以有 锁表,锁行,锁住一个范围(gap)

按照锁的模式有:共享,排他,意向

1)共享锁 S lock 允许事务都取一行数据

2)排他锁 X lock 允许事务删除或者更新一行数据

2e986bbdcc7a4279e1a739722b3ba966.png

3)意向共享锁 IS

4)意向排他锁 IX

意向锁的作用

意向锁锁的粒度是表级别的锁,行排他锁 和表排他锁锁是不兼容的,如果事务A加了某行 行排他锁,事务B 要加一个表级别排他锁,事务B 怎么判断有了行锁呢,它需要遍历表中所有行记录判断有没有行排他锁,这种判断效率太低,那么可以通过意先锁来处理,事务A 加排他行锁时,会在表级别上加意向排他锁,事务B在加表排他锁时,直接查看有没有在表上的意向锁,如果有的话,就阻塞。

通过意向锁来串起两个不同粒度(表 行)的锁之间如何做互斥判断

5)间隙锁(gap lock)临建锁(next-key lock)

案例:

建立表t,插入主键值1,2,3,4,7,8, 6条记录,在事务为可重复读的情况下开启两个会话,会话A执行

Select* from t where a<6 lock in share mode 在会话A 没有提交事务释放锁的时候 ,开启会话B执行

Insert into t 5,那么会话B会阻塞,事务A 有一个next-key lock 锁定(负无穷到6),如果插入的不是这个范围的是可以的。在事务隔离级别是 可重复读的模式下,就是加了范围锁,保证事务可重复读。

五 一致性非锁定读,多版本控制(MVCC)

非锁定读是没有阻塞的,读取不会占用和等待表上的锁,它读取是是行记录版本快照

,在读已提交的事务级别,一致性非锁定读是被锁定行的最新的一份快照

在可重复读的事务级别,一致性非锁定读 读取的是事务开始时候的数据版本

示例:

事务A读已提交

cce3a54d46dff959eb9ed3a6bd9fa1d5.png

事务A可重复读情况

3607e6f6341ebf08bbe33a843186ee15.png

Mvcc原理

1) DATA_TRX_ID:最近更新这条记录的Transaction ID,数据库每开启一个事务,事务ID都会增加,每个事务拿到的ID都不一样

2) DATA_ROLL_PTR:用来存储指向Undo Log中旧版本数据指针,支持了事务的回滚

事务读已提交情况:事务A 插入数据Insert into table value 1,2018-4-28

fd07adcc6b8407692f03aa665cac0054.png
72ece37d1a0cda6b335a66ac6bdfd25c.png
8fe52d14cafefdd6b0a60395cdc770ed.png

当前读的事务ID为read_id,记录当前存储的事务ID为tid,当前系统中未提交的事务中(Read_View中)的最大最小事务ID分别为max_tid和min_tid,那么数据时间点3情况

read_id=3,tid=2,Read_view(2,3)

时间点5

read_id=3,tid=2,Read_view(3,3)

如果事务是可重复读 Read_view(2,3)

六 读加锁 select ...for update 和select .. lock in share mode

除串行select语句都是非一致性锁定读,如果需要读加锁 可以用for uodate 和lock in shard mode 语句。

1)for update 读取的行 加排他锁。

2)Lock in shard mode 读取的记录加共享锁。

事务没有提交锁是不会释放的。

七 事务并发导致的问题

6ddc5829ebf343cf87779e8468952a70.png

八 事务隔离级别

e1dae949c1c062dec7f8967f4500d5e6.png

怎么解决更新丢失问题?

案例:商品(product)库存量 (Stock)并发扣减问题

减库存代码逻辑

Select stock from product where id =1If(stock==0){ 扣减失败,提示库存不足}Update product set stock-1 where id =1

多线程并发访问 会出现库存为-1的情况,原因事务 AB 同时读取到库存为1,查询和共享操作没有原子性。

解决方法

1利用单个sql语句的原子性

Update product set stock-1 where id =1 and stock >0

2 悲观锁

Select stock from product where id =1 for updateIf(stock==0){ 扣减失败,提示库存不足}Update product set stock-1 where id =1

3乐观锁 CAS思想

While(!result){ Select stock,version from product where id =1 If(stock==0){ 扣减失败,提示库存不足 } result =update product set stock-1 ,version=version+1 where id =1 and version =version}

4 单机synchronized,注意锁的粒度是在当前的商品,分布式锁

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值