| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 大数据 -> 数据库事物概览 -> 正文阅读 |
|
[大数据]数据库事物概览 |
数据库事物概览ACID原子性:当客户想进行多次写入,但在一些写操作处理完之后出现故障的情况。例如进程崩溃,网络连接中断,磁盘变满或者某种完整性约束被违反。如果这些写操作被分组到一个原子事务中,并且该事务由于错误而不能完成(提交),则该事务将被中止,并且数据库必须丢弃或撤消该事务中迄今为止所做的任何写入。 隔离级别与异常现象ANSI SQL-92 提出了最经典的隔离级别定义,包括读未提交(Read Uncommitted)、读提交(Read Committed)、可重复读(Repeatable Read)和可序列化(Serializable)。 Dirty Write如果先前的写入是尚未提交事务的一部分,又会发生什么情况,后面的写入会覆盖一个尚未提交的值?这被称作脏写(dirty write),任何隔离级别都应该防止脏写的产生。 以一个二手车销售网站为例,Alice和Bob两个人同时试图购买同一辆车。购买汽车需要两次数据库写入:网站上的商品列表需要更新,以反映买家的购买,销售发票需要发送给买家。在下图中,销售是属于Bob的(因为他成功更新了商品列表),但发票却寄送给了爱丽丝(因为她成功更新了发票表)。 Dirty ReadDirty Read 的解释是一个事物读取到还未提交的事务的写入内容就算发生了 Dirty Read。 Repeatable ReadRepeatable Read 指的是两次读操作读到了不同的数据。
Phantom ReadPhantom Read 指的是,在一个事物中,前期通过读取操作(select)获得的信息,不足以支撑我最后的写操作(insert,update,delete)。根本原因在于 MySQL 读的时候是快照读,但是写的时候是写最新版本。
业务程序员的错误指业务程序员使用了不合适的隔离级别来操纵数据库,导致得到的最终结果不符合业务的一致性(consistency)。 Read Skew错误的使用了会产生 Repeatable Read 的隔离级别(Read Uncommitted,Read Committed)。 爱丽丝在银行有1000美元的储蓄,分为两个账户,每个500美元。现在一笔事务从她的一个账户中转移了100美元到另一个账户。如果她在事务处理的同时查看其账户余额列表,不幸地在转账事务完成前看到收款账户余额(余额为500美元),而在转账完成后看到另一个转出账户(已经转出100美元,余额400美元)。对爱丽丝来说,现在她的账户似乎只有900美元——看起来100美元已经消失了。 Lost Update错误的使用了非 Serializable 的隔离级别。 (假设数据库中没有自增操作)每个客户端需要读取计数器的当前值,加 1 ,再回写新值。下图中,因为发生了两次增长,计数器应该从42增至44;但由于竞态条件,实际上只增至 43 。 Write Skew错误的使用了非 Serializable 的隔离级别。 首先,想象一下这个例子:你正在为医院写一个医生轮班管理程序。医院通常会同时要求几位医生待命,但底线是至少有一位医生在待命。医生可以放弃他们的班次(例如,如果他们自己生病了),只要至少有一个同事在这一班中继续工作。 再看一个例子,即 T1 尝试把 x 的值赋给 y,T2 尝试把 y 的值赋给 x,如果这两个事务 Serializable 的执行,那么在结束之后 x 和 y 应该拥有一样的值,但是在 Write Skew 中,并发操作使得他们的值互换了。 可以将写入偏差视为丢失更新问题的一般化。如果两个事务读取相同的对象,然后更新其中一些对象(不同的事务可能更新不同的对象),则可能发生写入偏差。在多个事务更新同一个对象的特殊情况下,就会发生丢失更新。 避免 Lost Update & Write Skew在 Serializable 的隔离级别中进行操作当然避免,但是如何在 Repeatable Read 隔离级别中避免 Lost Update & Write Skew。 假设有A、B两个用户同时各购买一件 id=1 的商品,用户A获取到的库存量为 1000,用户B获取到的库存量也为 1000,用户A完成购买后修改该商品的库存量为 999,用户B完成购买后修改该商品的库存量为 999,此时库存量数据产生了不一致。(类似上面计数器的例子) 有两种解决方案: 悲观方案:每次获取商品时,对该商品通过
乐观方案:每次获取商品时,不对该商品加锁。在更新数据的时候需要比较程序中的库存量与数据库中的库存量是否相等,如果相等则进行更新,反之程序重新获取库存量,再次进行比较,直到两个库存量的数值相等才进行数据更新。乐观锁适合读取频繁的场景。
参考https://juejin.cn/post/6844903927536844808 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 10:34:05- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |