闲话MVCC

本文深入探讨了事务的概念及其在数据库操作中的作用,包括事务的开始、提交、回滚,以及不同隔离级别的实现与特性。重点阐述了事务如何帮助开发者聚焦业务逻辑,而非底层实现细节,同时介绍了MySQL的事务APIs及MVCC机制如何优化并发控制,减少数据一致性问题。
摘要由CSDN通过智能技术生成

为什么需要事务

其实和我们需要是一个道理。因为我们业务上的一个逻辑操作单元Tx_A,对应的是多个计算机指令。我们需要一种机制来确保在Tx_A操作执行期间,其内部状态不可以被外界观测到。如果外界访问,要么阻塞等待直到该操作结束。要么直接返回告诉它,“Sorry ,I’m busy now”。事务就是这样一种机制。做数据库的大神说,“得了,您也别自己去实现这样一种机制了,就我实现得了。你们会用就行,免得一大堆bug”,所以事务的出现使得我们能更好focus在我们的业务上。而不用自己去实现事务等价一套APIs。
事务是一个说明性的概念,这个概念用来表述你想要达到什么样的效果。

Mysql对外暴露的事务APIs如下:

  • 1.事务的开始
    • START TRANSACTION
    • BEGIN
  • 2.事务提交
    • COMMIT
  • 3.事务回滚
    • ROLLBACK

ANSI/ISO isolation(隔离级别)

一言以蔽之,隔离级别是事务之间可见性的定义。

1. 可序列化(Serializable)

可序列化涉及到范围锁(主要是用于解决聚集查询),所以没有幻读问题。

2.可重复读(READ-REPEATABLE)

在可重复读取(REPEATABLE READS)级别下,数据库系统会在整个事务期间保持读取锁写入锁。但相较于可序列化,范围锁不会持有,所以幻读可能会出现。

Ps:MySQL的MVCC兼容此隔离级别,并且避免了幻读问题。

3.不可重复读(READ-COMMITTED)

在READ COMMITTED级别下,整个事务期间保持写入锁,但读取锁会在SELECT执行之后立即释放。所以也称为NON-REPEATABLE READ。

4.读未提交(READ-UNCOMMITED)

在此隔离级别下,脏读可能会出现。
Ps:此处需要注意脏读含义的理解。
事务A如果可以看见其它事务的中间状态,那么就是脏读。换句话说,一个事务能看见的数据,要么在其它事务开始之前,要么是之后。事务是将数据库状态从某个一致的状态,变成另一种一致的状态。

小结

以MySql为例,大多数应用采用的隔离级别为REPEATABLE READ,所以SELECT读到的数据可能不是目前最新的(可见性?)。其实对大多数业务来说都OK,因为大多数业务并不要求全局的happen-before关系,而只要求某几个操作之间有。

MVCC

以隔离级别「READ-REPEATABLE」为例,按照上面「读写锁」的实现,那么读写依然是冲突的,能不能达到读写也不冲突呢?毕竟人类对性能的追求是无止境的。答案是肯定的。其思想上和Java的CopyOnWriteArrayList极为类似。简单来说
就是通过”volatile+写锁”实现。这样就可以实现
读写不互斥(通过volatile);
还是以经典的Bob给Simith转账100刀为例.

事务A
start
update account set balance=balance where id=’bob’ and balance >=100
commit;
事务B
start;
select balance where id=’bob’
commit;
现在假设事务A和事务B并行执行,照例说事务B,应该会等事务A提交时候( 提交会释放锁),之后才会读到bob账户余额,事实上由于读余额时,并不会尝试获取写锁,所以无需等待。所以读写不互斥。
Ps:肯定有同学会疑惑,这样不就是读得不是最新的了嘛?的确,这样读到的数据不是最新的,但是为什么需要读到最新的呢,对大多读事务场景,并不需要读到最新值啊,如果是写事务的话,那么对业务属性是否满足更新条件,必须放在update的where子句中,而不能先select后update,当然,对大多数应用,先selelct 如果(不)满足,然后(不)更新,如果大多数条件都不用更新,那么这么写,可能会有性能优化,毕竟select 无锁,update可是必须要锁的。

显示锁

隐式锁

  • select 隐式获取与释放读锁

写时复制(COW(Copy-On-Write))的

参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值