CC 咖啡猫的工作空间 Coding Space

一、本地事务

  1. 事务四大特性:A(原子性,undo log保证)C(一致性,目的)I(隔离性,锁+MVCC实现)D(持久性,Redo log实现)
  2. 事务隔离级别:未提交读、已提交读、可重复读(默认隔离级别,InnoDB通过临键锁解决)、串行化
  3. MVCC多版本并发控制原理
  • 快照读(读取历史版本)和当前读(读取最新数据,加锁)
  • 三要素:隐藏列(DB_TRX_ID:最近修改的事务ID, DB_ROLL_PRT:指向Undo Log的指针, DB_ROW_ID:行ID)、ReadView(读取视图)、版本链(新事物修改 -> 生成新版本 -> 指向前一个版本)
  • MVCC查询逻辑:事务A开启(生成ReadView)-> SELECT(读取数据时)-> 检查数据行的事务ID -> DB_TRX_ID < min_trx_id(检查数据是否在事务A开启前已提交?已提交则读取数据,否则进入下一步) -> DB_TRX_ID 在 m_ids 中(数据是并发事务修改?沿着版本链找;数据是已提交事务修改?可读取)
  • 可见性判断:事务A开启(隔离级别:RR,读取到事务A开启时的快照),事务提交后再次查询,仍然读取到旧值,因为ReadView未变(实现了可重复读)。
  1. 快照读与当前读:快照读(MVCC,不加锁)、当前读(加锁)
  2. Next-Key Locks:锁住索引范围,防幻读
  3. 多事务修改丢失更新:悲观锁(select ... for update)、乐观锁(版本号,更新是version不匹配,说明被其他事务更新了,返回失败)
  4. 死锁(查看死锁日志:SHOW ENGINE INNODB STATUS):T1持有A锁,等待B锁;T2持有B锁,等待A锁。处理办法:InnoDB 自动检测死锁,回滚代价最小的事务;业务层重试。

二、分布式事务(不要在事务中嵌套外部调用:最直接的后果就是事务执行时间变长。)

  1. CAP定理:CAP定理,CAP定理的结论是:一个分布式系统最多只能同时满足两个条件:一致性可用性,不能同时满足一致性分区容错性(网络挂掉形成分区,网络分区无法避免)
  2. BASE理论:基本可用(即使部分节点不可用,也能保证系统可用)软状态(软状态,系统状态不是固定的,状态会随时改变,但最终经过一段时间后达到一致)
  3. 2pc提交(追求强一致性+原子性):prepare、commit、rollback
  4. 3pc提交(引入了超时机制,避免无线阻塞。理论意义大于实际,生产环境较少使用):询问CanCommit、预提交PreCommit、执行提交DoCommit
  5. TCC(代码入侵性强):try-confirm-cancel
  6. SAGA(适用于长事务):尝试无拆分为多个子事务
  7. Seata框架(重量级方案,适合对一致性要求极高的场景):AT(自动模式,对比2PC)、TCC(代码入侵性高,开发成本大)、SAGA(长事务状态机,适合业务流程复杂的场景)
  8. RocketMQ事务消息(最终一致性,半消息机制保证本地事务和消息发送的原子性):发送方(发送半消息:MQ内部隐藏队列,对消费者不可见、执行本地事务、提交or回滚半消息)、MQ(提交->消费者可见、回滚->丢弃半消息)、补偿机制(未收到确认:也就是发送方本地事务的执行结果是提交还是回滚->MQ回查发送方本地事务状态、发送方根据本地事务结果回复)
  9. 总结:对于80%以上的业务场景,MQ + 最终一致性是最优解。数据库事务应该是“快进快出”的短作业,永远不要让它去等待不可控的网络 IO(不要在事务中嵌套外部调用,如缓存、外部接口、消息队列、文件存储等)。