[#0x0034] Isolation

数据库隔离级别详解
本文介绍了数据库系统的四种隔离级别:Read Uncommitted、Read Committed、Repeatable Read 和 Serializable,并详细解释了每种级别如何处理并发问题,如脏读、不可重复读和幻读。

  参考Wikipedia: http://en.wikipedia.org/wiki/Isolation_(database_systems)#Repeatable_reads_.28phantom_reads.29  

 

  Isolation的理想状态是:the result of Transaction A is invisible to Transaction B until Transaction A is completed。不过这么一来,只有Serializable级别才能满足要求,即Transactions是一个接一个地执行,不允许Transactions的并行。如果想要Transactions的并行,那么就不可能有绝对的isolation。为此,ANSI/ISO制定的SQL标准给Isolation分了4个级别,由高到低分别是:

  • Serializable
  • Repeatable Read (Phantom Read)
  • Read Committed (Nonrepeatable Read)
  • Read Uncommitted (Dirty Read)

级别越高的,isolation性越好,而低级别的isolation会有各种各样的并发问题(如上面括号中所示)。下面一一介绍。

 

1. Read Uncommitted

  Transaction 1可以查看Transaction 2未提交的操作结果,这会导致Dirty Read的问题,如下图所示:

 

dirty read

Transaction 1的执行的第二个query会读到Transaction 2中update的结果,如果Transaction 2 rollback的话,这个读到的数据明显是错误的。

 

2. Read Committed

  如果我们强制Transaction 1只能读Transaction 2中已经commit的update,就可以解决Dirty Read的问题。强制的手段是:每次query(比如SELECT)时,都会获取当前数据库(或者可能只是query涉及的表)的一个snapshot,query从这个snapshot中获得结果。没有commit的update不会在snapshot中出现,所以就不会被query到。

  这样允许Transaction 2并行执行,且不会影响Transaction 1。当Transaction 1 commit的时候,DBMS检测是否有冲突(比如Transaction 1也update了Transaction 2中update的row),如果执行的结果等同于顺序执行Transaction 1和 Transaction 2 ,则认为没有冲突。

  但这样也会有问题:Nonrepeatable Read,即可能执行同一query两次而出现不同的结果,我们认为这是不符合一致性原则的。

nonrepeatable read

 

3. Repeatable Read

  解决Nonrepeatable Read问题的办法是给Transaction 1中的SELECT涉及的行加一个read lock。

  锁的排斥功能很明确:read locks不会block read locks,只block write locks;write locks block both read locks and write locks。

  不过会有新的问题:phantom read。

 

phantom read

 

当Transaction 1执行一个range query(范围查询,如like, between等)时,只会为涉及到的row加read lock,如果插入一个新row在range之内,第二次range query还是会被读出。

 

4. Serializable

  强制Transactions按顺序执行,所以Transaction之间不可能冲突。强制的手段是给place a read lock on every row the transaction read;同时,如果有range query,还会添加一个range lock。明显,Serializable会耗费很多的lock overhead。

  Serializable相当于在Transaction 1开始时(而不是query开始时)给当前数据库(或是Transaction涉及的表)take a snapshot,Transaction 1中的所有query都从这一个snapshot中获取结果。

 

获取到目标进程PID: 27118 libil2cpp.so 内存映射段(共53段): 段1: 0x000000764f2aa000 - 0x0000007654c2a000(长度: 0x0000000005980000) 段2: 0x0000007654c2a000 - 0x0000007654c2c000(长度: 0x0000000000002000) 段3: 0x0000007654c2c000 - 0x0000007654c34000(长度: 0x0000000000008000) 段4: 0x0000007654c34000 - 0x0000007654c35000(长度: 0x0000000000001000) 段5: 0x0000007654c35000 - 0x0000007654c39000(长度: 0x0000000000004000) 段6: 0x0000007654c39000 - 0x0000007654c3c000(长度: 0x0000000000003000) 段7: 0x0000007654c3c000 - 0x0000007654c98000(长度: 0x000000000005c000) 段8: 0x0000007654c98000 - 0x0000007654c99000(长度: 0x0000000000001000) 段9: 0x0000007654c99000 - 0x0000007654c9d000(长度: 0x0000000000004000) 段10: 0x0000007654c9d000 - 0x0000007654c9e000(长度: 0x0000000000001000) 段11: 0x0000007654c9e000 - 0x0000007654c9f000(长度: 0x0000000000001000) 段12: 0x0000007654c9f000 - 0x0000007654ca0000(长度: 0x0000000000001000) 段13: 0x0000007654ca0000 - 0x0000007654ca4000(长度: 0x0000000000004000) 段14: 0x0000007654ca4000 - 0x0000007654ca5000(长度: 0x0000000000001000) 段15: 0x0000007654ca5000 - 0x0000007654ca6000(长度: 0x0000000000001000) 段16: 0x0000007654ca6000 - 0x0000007654ca7000(长度: 0x0000000000001000) 段17: 0x0000007654ca7000 - 0x0000007654f2c000(长度: 0x0000000000285000) 段18: 0x0000007654f2c000 - 0x0000007654f2d000(长度: 0x0000000000001000) 段19: 0x0000007654f2d000 - 0x000000765556e000(长度: 0x0000000000641000) 段20: 0x000000765556e000 - 0x000000765556f000(长度: 0x0000000000001000) 段21: 0x000000765556f000 - 0x0000007655591000(长度: 0x0000000000022000) 段22: 0x0000007655591000 - 0x0000007655592000(长度: 0x0000000000001000) 段23: 0x0000007655592000 - 0x00000076555a7000(长度: 0x0000000000015000) 段24: 0x00000076555a7000 - 0x00000076555a8000(长度: 0x0000000000001000) 段25: 0x00000076555a8000 - 0x00000076555c3000(长度: 0x000000000001b000) 段26: 0x00000076555c3000 - 0x00000076555c4000(长度: 0x0000000000001000) 段27: 0x00000076555c4000 - 0x0000007655722000(长度: 0x000000000015e000) 段28: 0x0000007655722000 - 0x0000007655723000(长度: 0x0000000000001000) 段29: 0x0000007655723000 - 0x0000007656a7e000(长度: 0x000000000135b000) 段30: 0x0000007656a7e000 - 0x0000007656a7f000(长度: 0x0000000000001000) 段31: 0x0000007656a7f000 - 0x0000007656a81000(长度: 0x0000000000002000) 段32: 0x0000007656a81000 - 0x0000007656a82000(长度: 0x0000000000001000) 段33: 0x0000007656a82000 - 0x00000076571a2000(长度: 0x0000000000720000) 段34: 0x00000076571a2000 - 0x00000076571a4000(长度: 0x0000000000002000) 段35: 0x00000076571a4000 - 0x00000076576c4000(长度: 0x0000000000520000) 段36: 0x00000076576c4000 - 0x00000076576c5000(长度: 0x0000000000001000) 段37: 0x00000076576c5000 - 0x0000007657a31000(长度: 0x000000000036c000) 段38: 0x0000007657a31000 - 0x0000007657a32000(长度: 0x0000000000001000) 段39: 0x0000007657a32000 - 0x0000007657a36000(长度: 0x0000000000004000) 段40: 0x0000007657a36000 - 0x0000007657a37000(长度: 0x0000000000001000) 段41: 0x0000007657a37000 - 0x0000007657a53000(长度: 0x000000000001c000) 段42: 0x0000007657a53000 - 0x0000007657a54000(长度: 0x0000000000001000) 段43: 0x0000007657a54000 - 0x0000007657ab6000(长度: 0x0000000000062000) 段44: 0x0000007657ab6000 - 0x0000007657ab7000(长度: 0x0000000000001000) 段45: 0x0000007657ab7000 - 0x0000007657b64000(长度: 0x00000000000ad000) 段46: 0x0000007657b64000 - 0x0000007657b65000(长度: 0x0000000000001000) 段47: 0x0000007657b65000 - 0x000000765856d000(长度: 0x0000000000a08000) 段48: 0x000000765856d000 - 0x000000765856e000(长度: 0x0000000000001000) 段49: 0x000000765856e000 - 0x000000765a824000(长度: 0x00000000022b6000) 段50: 0x000000765a834000 - 0x000000765b728000(长度: 0x0000000000ef4000) 段51: 0x000000765b90a000 - 0x000000765b90d000(长度: 0x0000000000003000) 段52: 0x000000765b91a000 - 0x000000765b91f000(长度: 0x0000000000005000) 段53: 0x000000765b922000 - 0x000000765b924000(长度: 0x0000000000002000) 进程已暂停(PID: 27118) 请输入目标地址(十六进制,例如7B29F2E168): 764F2AA004 请输入要写入的整数值(十进制,例如123456789): 65791 页备份成功(页起始地址: 0x000000764f2aa000) 成功: 使用syscall 124 刷新缓存 缓存强刷新成功 页已恢复(原始值已写回) 进程已恢复运行(PID: 27118) 进程已恢复运行,正在执行原始逻辑... 恢复后的值: 65794 验证成功:值已恢复为原始值 成功: 使用syscall 124 刷新缓存 验证成功:CPU执行的是新指令 Hook完成!进程已恢复正常运行 打印都没问题 但执行的指令逻辑是依然是旧的不是新的 我已经没有任何思路修复 红米k70 安卓14 5.15内核 具备root环境
07-14
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值