ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

《DDIA》读书笔记:事务

2022-02-10 18:35:08  阅读:314  来源: 互联网

标签:事务 快照 读书笔记 read update compare content 线程 DDIA


目录

本文是第七章Transaction部分的读书笔记。

这部分包括的内容为:

  • ACID的含义
  • 读已提交和它存在的问题
  • 快照隔离(可重复读)和它存在的问题
  • 可串行化的实现方法

个人感觉这部分的亮点在于对 lost update 和 Write Skew and Phantoms 的分析.
我的总结就是3种情况: read-modify-write, read-compare-update, read-compare-insert

ACID

Atomic - 没有中间状态,要么成功,要么失败
Consistency - consistency refers to an application-specific notion of the database being in a “good
state". 从应用的角度要求数据库处于正确的状态
Isolation - concurrently executing transactions are isolated from each other.
Durability - once a transaction has committed successfully, any data it has written will not be forgotten

读已提交

  • When reading from the database, you will only see data that has been committed (no dirty reads). 不存在赃读
  • When writing to the database, you will only overwrite data that has been com‐ mitted (no dirty writes). 不存在赃写

问题:事务内两次相同的读操作可能得到不同的结果,即不可重复读

快照隔离(可重复读)

原则是读和写之间不冲突,通常用MVCC实现。存在的问题: lost update, Write Skew and Phantoms

问题1: lost update. 两个线程同时执行read-modify-write的流程,有一个线程的修改会被另一个线程覆盖掉。例如2个线程同时向一个账户转账200元,转账前账户余额为500元,线程都将更新的值设为700,那么账户的最终余额为700元,丢失了200元

解决

  • 使用原子更新操作。UPDATE counters SET value = value + 1 WHERE key = 'foo';
  • read的时候显式的加锁,避免其他线程读
  • 自动检测lost update的发生,如果会发生更新丢失,abort当前transaction。pg的RR有,InnoDB的RR没有
  • compare-and-set. UPDATE wiki_pages SET content = 'new content' WHERE id = 1234 AND content = 'old content';但要求compare的必须是最新的数据,例如RR隔离级别下的MySQL,content='old content'是快照读,是读不到最新数据的

问题2: Write Skew and Phantoms.

发生的情况为read-compare-write,流程如下

  • 1 读数据
  • 2 根据读出的数据判断条件是否符合
  • 3 如果符合就执行写操作
  • 但第3步的写操作会让第2步的条件由符合变为不符合

具体可以分为read-compare-update和read-compare-insert两种情况

  • read-compare-update. 有三名医生A、B、C,要求任意时刻至少有一名医生是未被预约的。A已被预约,然后来了用户1和2,1看到B和C都可以被预约,满足可预约条件,就预约了B,2同样看到B和C都可以被预约,就预约了C,1和2都执行完后,3名医生都被预约了,就违背了最开始的要求。这种情况可以在read时加锁来解决这个问题,SELECT FOR UPDATE
  • read-compare-insert. 为了保证用户名唯一,为用户分配用户名时,先判断用户名是否存在,如果不存在就插入该用户名,结果就是并发执行的情况下,多个记录有相同的用户名。MySQL的Next-key Lock可以解决这个问题

This effect, where a write in one transaction changes the result of a search query in another transaction, is called a phantom

可串行化

实现方法1: 单线程写。例如Redis

实现方法2: Strong strict two-phase locking(SS2PL)。
InnoDB和SQL Server的可串行化隔离级别就用的该方法实现。这种方法不同于快照隔离要求的对同一条记录的读写不冲突,它是读写互斥

  • 读的时候要加读锁
  • 写的时候要加写锁
  • 如果是先读后写,先持有读锁,写的时候变为写锁
  • 一旦持有锁,事务结束时才会释放
  • 问题:更容易产生死锁,性能比较差
  • 加什么锁:为了避免插入幻影记录,加的锁一般都是index-range locking(或称为next-key locking)

实现方法3:Serializable Snapshot Isolation (SSI)。一种乐观的并发控制技术

  • based on snapshot isolation—that is, all reads within a transaction are made from a consistent snapshot of the database. 基于快照隔离
  • adds an algorithm for detecting serialization conflicts among writes and determining which transactions to abort. 检测冲突,然后决定哪些事务该abort

参考:
Designing Data-Intensive Applications https://book.douban.com/subject/26197294/

标签:事务,快照,读书笔记,read,update,compare,content,线程,DDIA
来源: https://www.cnblogs.com/elimsc/p/15880316.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有