'事务-分布式事务'

传统事务

事务,即是通过锁控制并发访问。

锁粒度越大,越安全,效率越低;

锁粒度越小,并发高,越不安全。

并发场景:

​ 读读、读写、写读、写写

什么是ACID

  1. 原子性(Atomicity)

    整个事务,要么全部执行,要么全部不执行。有异常,回滚到执行前状态。

    • 记录undo日志,能回滚到之前状态
    • 不保证(不一致的)中间结果不被外部看到
  2. 一致性(Consistency)

    不能破坏关系数据的完整性,以及业务逻辑的一致性。

    • 加锁
    • 保证中间结果不被外部看到
  3. 隔离性(Isolation)==以性能为理由,对一致性的破坏==

  4. 持久性(Durability)

    事务完成后,改动被持久化存储。不会回滚。

    • 磁盘损坏:RAID(保证两块磁盘数据一致,分布式)
    • 内存 –> 磁盘:
      • 批持久化
      • 逐条持久化
      • group committed
        • 延时提交
        • 攒够几个一起提交

读写锁

锁:

  1. 全局锁(串行化)
  2. 表级锁
  3. 数据锁
  4. 数据读写锁
  • 读锁:读数据时加锁,可以并发读。但不能写。
  • 写锁:不能并发读,也不能并发写。

数据库隔离级别

隔离级别的存在,提高并发,破坏了一致性。

  • read uncommitted

    • 无读锁、有写锁————读读、读写、写读并行
  • read committed

    • 有读锁、有写锁,读锁可升级为写锁—————读读、读写并行
  • read repeatable

    • 有读锁、有写锁,读锁不可升级写锁—————读读并行
  • serializable

    • 串行化(读时,阻止新数据插入)——————无并行
  • 拓展的隔离级别:snapshot(以上为SQL92标准定义)

    当前被映射回SQL92标准的read uncommitted 或者 read committed

    • MVCC(当下各流行数据库均有使用)
    • 无锁编程

多版本并发控制(MVCC - multi version concurrent control)

核心:copy on write

==优化“写读并发”场景==

  • 用新的方式,实现传统意义上read uncommitted场景;同时保证可序列化的隔离级别
  • 写多,读少,反而增加系统成本
  • 适合读写比率高的场景
拓展(引出的问题):

​ 实现复杂度高。

​ 旧版本数据,什么时候删除。undo log/redo log超长。

常见问题

  1. 事务先后

    给事务加ID、时间戳。标记事务先后。

  2. 故障恢复

    • 业务属性不一致,回滚

      需记录事务中,所有操作的反向操作。

    • 数据库崩溃,恢复

      先回滚未完成事务,完成后暴露对外访问。

  3. 死锁、死锁检测

    • 碰撞检测(高效)

      检查事务A请求的锁,被谁持有;持有锁的事务B,又在请求什么锁;该锁刚好被A持有,则判定为死锁。 回滚一个事务即可。

    • 等锁超时

调优原则

  • 减少锁的覆盖范围
  • 增加锁上可并行的线程数
  • 选择正确的锁类型
    • 悲观锁
      • 使线程到blocking状态(等待被唤醒)
      • 导致频繁切换寄存器数据,缓存、cpu cache被清空。换成下一个线程的数据。
      • 适用并发争抢严重场景
    • 乐观锁
      • 适用并发争抢不太严重场景(锁阻塞时间短、请求并发度不高,可以很快抢到锁)