ACID性质是数据库理论中的奠基石,它定义了一个理论上可靠数据库所必须具备的四个性质:原子性,一致性,隔离性和持久性。虽然这四个性质都很重要,但是隔离性最为灵活。大部分数据库都提供了一些可供选择的隔离级别,且现在许多库都增加了附加层来创建颗粒度更细的隔离。隔离级别应用范围如此之广主要是因为放宽隔离约束往往会使得可扩展性和性能提高几个数量级。
串行一致性是可用的最古老最高的隔离级别之一,它之所以倍受青睐是因为其提供的简单编程模型,即每次仅能有一个事务对给定的资源进行操作,这就避免了很多潜在的资源问题。尽管如此,大部分应用程序(尤其是Web应用程序)都不采用这种级别非常高的隔离,因为从终端用户的角度来看这是不切实际的-任何一个拥有大量用户群的应用程序在访问共享资源时都将会有几分钟的延迟,而这会使得用户量迅速减少。弱一致性和最终一致性在大规模分布式数据源中,例如Web中,随处可见。好几个成功的大型Web应用(例如,eBay和Amazon)都显示出乐观的(optimistic)弱一致性要比传统悲观的(pessimistic)机制在扩展性方面好得多。本文将一窥八种不同的隔离级别。学会适当的放宽数据一致性的约束,你可以在自己的应用程序中使用这八种隔离级别来获得更好的性能和可扩展性。
并发控制的主要目标是为了确保事务被隔离且不会影响到其他事务。要达到高级别的隔离需以牺牲性能为代价。并发控制可以用悲观或者乐观的机制来实现。大部分关系型数据库都使用了悲观机制来实现写入优化。悲观机制采用了锁,通过使用锁它可以阻塞一些操作或者进行某些形式的冲突检测。当一个表格,页面或是行被修改后,悲观机制中的锁可以用来阻塞其他潜在的访问修改资源的事务。然而,乐观机制并不采用任何锁,它仅仅依赖于冲突检测来维护事务隔离。乐观机制采用的冲突检测可以允许所有的读操作,并在事务结束时检验其一致性。如果检测到冲突,那么事务会进行回滚或重做。大部分web服务器都是读入优化,因此使用了乐观机制。通过允许所有的读入操作,乐观机制既可以保证很高的读写吞吐量,也可以在资源不是一直改变的情况下保证数据的一致性。
下面列出的隔离级别是用来帮助Web开发人员更好的理解他们编程模型中放置的约束,帮助系统架构师和开发人员共同讨论如何在保持必要的数据完整性的同时选择最有效的隔离级别。它们按照最少隔离(未提交读)到最多隔离(串行化)的顺序列出。
1、未提交读(Read Uncommitted)
未提交读隔离级别需要事务间很少的隔离。每一个读操作都能看到事务中等待的写操作(脏读)。然而已经提交的写操作必须要有一个串行顺序来防止脏写。悲观机制会阻塞有冲突的写操作直到其他写操作已经被提交或已经回滚。乐观机制不会锁住这些操作,它会允许所有的操作都通过。如果一个连接进行了回滚,那么接下来修改同一块数据的其他操作也会被回滚。在这种级别中,共享缓冲可以不加验证的进行使用。这种隔离级别最好在不需要事务(比如只读的数据集),或者事务只在独占数据库时才修改的情况下使用。
例子:一个只在离线情况下更新的档案数据库,或者不在事务中使用的审核/登陆(audit/logging)表。
2、已提交读(Read Committed)
已提交读可以读取系统中任何已经提交的状态,并且可以不加验证(混合状态)的进行缓冲,只需当前连接中发生的改变能够反映到结果中即可。悲观机制将其实现为单调视图。乐观事务则隔离存储所有的改动,使得它们直到提交后才可用。读已提交使用一个非常乐观的机制,它推迟写入所有的变化直到事务被提交为止。这种形式的乐观隔离可以在不阻塞读操作的情况下实现复杂的写入操作,并且它没有验证模式。共享缓冲只能在已提交的状态中使用。这种隔离级别最好在结果可以使用旧值,且事务只能用于写入操作的情况下使用。
例子:一个不必显示当前最新帖子的在线论坛,且它的帖子间数据不相冲突。
3、单调视图(Monotonic View )
单调视图是对读已提交的一个扩展,它其中的事务在执行时会观察数据库中一个单调上升的状态。在这种级别中,如果有明显的写入事务,那么悲观事务会在读入操作中被阻塞。乐观事务会像在读已提交中一样操作,隔离保存所有的改动,并且会验证它们的缓冲以确保其仍然合法。这种级别可以定期地同步数据库副本,且最好在不需要事务或者仅存在写操作事务的情况下使用。
例子:一个仅能由一个人来修改的用户偏好表。
4、快照读取(Snapshot Reads)
快照读取扩展了单调视图,它可以保证查询结果都能反映到数据库一致的快照中。悲观机制会在读操作时阻碍其他影响结果的写入操作。乐观机制则允许其他的写入操作,并通知读取事务某部分已经发生改变并进行回滚。想要实现一个乐观机制,必须在读操作结束之前验证是否有什么并行的写入操作修改了结果,如果有的话,那么结果可能会重做或回滚。这个检验过程可能只是简单的检查同一张表中是否出现了写入操作,或者只是检查改动的查询结果。乐观隔离级别可以很轻松地检测出冲突,并且在允许并发读入操作的过程中,支持写入操作。这种级别只要能够读取到快照,便可以定期地同步数据库副本。最好在写入操作很少,不想与读入操作冲突,且查询结果需要一致性的时候使用这种隔离级别。
例子::一个查询比修改频繁,且只保留最新值的货币换位表或者查询表。
5、游标稳定性(Cursor Stability)
游标稳定性隔离扩展了读已提交,并且是许多关系型数据默认的隔离级别。在这种隔离级别中,悲观事务如果在一个单独的语句中执行的话,必须得指定它将修改的记录。这通常可以在"SELECT"查询后附加“FOR UPDATE”关键字来实现。在这种情况下,其他冲突的读写悲观事务都将被阻塞直到该事务结束为止。乐观事务会跟踪提交时被验证的所有修改记录/实体的版本号。这是一种很流行的乐观隔离级别,因此被所有的主流对象关系映射库支持。在Java持久性API中,可以使用FLUSH_ON_COMMIT(尽管查询可能不影响本地改动)来接近达到这种级别,且如果检测到冲突的话,可以抛出OptimisticLockException 异常。这种隔离也同样可以用在HTTP头域的If-Match或者 If-Unmodified-Since中,它可以用来在更新前对比上一个资源的版本或者时间戳。这种级别最好在实体由外部信息(不从数据库中读取)更改,或者改动不会彼此覆盖的情况下使用。
例子:一个共享的公司目录或者一个wiki。
6、可重复读取(Repeatable Read)
可重复读取级别扩展了游标稳定性,它保证事务内的任何数据在事务过程中都不会被修改或者移除。悲观事务需要读取所有记录上的锁,并阻塞其他服务来修改这些记录。乐观事务则会跟踪所有的记录或者实体,并检查它们是否在提交时被修改过。这种级别最好在实体状态能够影响其他实体,或者事务由读写操作构成的情况下使用。
例子:一个订单跟踪数据库,它从一个实体中读取值并用它来计算其他的实体值。
7、快照隔离(Snapshot Isolation)
快照隔离扩展了快照读取和可重复读取,它保证事务中所有进行的读操作都能看到数据库中一致的快照。事务执行的的任何读操作都会有相同的结果,而不管它们在事务中执行的早晚。这和可重复读取不同,因为快照隔离能够防止幻读(查询结果不断变化)。许多关系型数据库采用多版本并发控制(也可以叫做 SERIALIZABLE)来支持这种级别,实现方法是通过锁和冲突检测的组合。在这种级别中,考虑到它可能与悲观机制或者乐观机制相冲突,因此事务一定要做好回滚的准备。悲观机制会通过锁住资源来尝试减少冲突的机会,但是必须在事务提交后将这些改动合并。乐观机制也会使用多版本并发控制,但是它不会阻塞其他可能产生潜在冲突操作的事务,反而是将冲突的事务进行回滚。这种级别的隔离最好在事务可以读取和修改多个记录的情况下使用。
例子:一个基于系统状态规则的工作流系统。
8、可串行性(Serializability)
串行性是快照隔离的扩展,它要求所有的事务都必须一个接着一个的出现,就好比它们被串行化过一样。悲观机制需要锁住所有评估过的查询,以防止写入操作影响这些结果。而乐观机制则跟踪所有评估过的查询,并在事务结束时使用一个后向验证或前向验证的模式来检查是否有并行写入操作影响了并行读入操作,如果有的话,它会将冲突事务外的所有事务进行回滚。在这种隔离级别中,任何提交事务都不会改变系统的表征状态。最好在需要完整数据一致性的情况下使用这个级别的隔离。
例子:一个进行范围查询来计算新值的账目系统。
总结
下面是本文提到的隔离级别的汇总表,它可以帮助你找到最适合你应用程序的级别。
事务在不同隔离级别中可能的冲突类型:
|
脏写 |
脏读 |
混合状态 |
不一致读 |
覆写 |
不可重复 |
幻读 |
不一致性 |
未提交读 |
不可以 |
可以 |
可以 |
可以 |
可以 |
可以 |
可以 |
可以 |
已提交读 |
不可以 |
不可以 |
可以 |
可以 |
可以 |
可以 |
可以 |
可以 |
单调视图 |
不可以 |
不可以 |
不可以 |
可以 |
可以 |
可以 |
可以 |
可以 |
快照读取 |
不可以 |
不可以 |
不可以 |
不可以d
|
可以 |
可以 |
可以 |
可以 |
游标稳定性 |
不可以 |
不可以 |
可以 |
可以 |
不可以 |
可以 |
可以 |
可以 |
可重复读取 |
不可以 |
不可以 |
可以 |
可以 |
不可以 |
不可以 |
可以 |
可以 |
快照隔离 |
不可以 |
不可以 |
不可以 |
不可以 |
不可以 |
不可以 |
不可以 |
可以 |
可串行性 |
不可以 |
不可以 |
不可以 |
不可以 |
不可以 |
不可以 |
不可以 |
不可以 |
不同隔离级别的最佳前提:
|
缓冲 |
数据同步 |
乐观冲突模式 |
建议操作 |
例子 |
未提交读 |
允许缓冲 |
间歇的 |
检测脏写 |
不能并发读写 |
档案 |
已提交读 |
允许缓冲 |
间歇的 |
没有冲突检测 |
单调的读/写 |
Web论坛 |
单调视图 |
必须被验证 |
周期的 |
没有冲突检测 |
组合读入 |
用户偏好 |
快照读取 |
必须被验证 |
周期的 |
对比读入与修改内容 |
一致性读入 |
查询表 |
游标稳定性 |
允许缓冲 |
间歇的 |
对比修改的实体版本 |
CRUD服务 |
目录 |
可重复读取 |
允许缓冲 |
间歇的 |
对比读入的实体版本 |
读/写实体 |
订单跟踪 |
快照隔离 |
必须被验证 |
周期的 |
对比读入的实体版本 |
同步实体 |
工作流 |
可串行性 |
必须被验证 |
完整同步 |
对比查询与修改内容 |
完善数据一致性 |
账目 |
数据一致性在数据库应用程序中至关重要-它允许开发者在分布式环境下使用数据。尽管强一致性级别如可串行性提供了一个简单的编程模型,但是它们会导致开销 过大,操作阻塞或者事务回滚,这对于很多应用程序来说都是不必要的。如果有其他问题的话,可以使用更加适当的隔离级别来帮助开发人员和系统架构师,让他们 在保持性能和开销平衡的前提下更好的理解数据一致性的需求。
分享到:
相关推荐
【数据库完整性控制与并发】是数据库管理中的核心概念,它们确保了数据库在多用户环境下的稳定性和一致性。数据库完整性控制确保数据的准确性和可靠性,而并发处理则解决了多个用户同时访问数据库时可能出现的问题。...
数据库完整性控制是数据库管理系统中的关键概念,其目的是确保数据的准确性和一致性,避免因错误输入或意外更改导致的数据损坏。本章主要介绍了四个主要的控制方法:约束、默认值、规则和事务处理。 首先,约束是...
标题提及的“电信设备-一种可信的数据库完整性保护方法及系统”是一个专门针对数据库安全性的研究,旨在提供一种可靠的方法来保护数据库的完整性,确保数据的准确性和一致性。 数据库完整性是数据库系统的一个关键...
数据库完整性约束条件是确保数据完整性的重要手段,包括: 1. 主键约束:唯一标识表中的每条记录。 2. 唯一约束:保证某一列或几列的组合值在表中是唯一的。 3. 检查约束:设置条件判断,只有满足条件的数据才能...
总结来说,保证数据库同步过程中的一致性和完整性是一项复杂而重要的任务,需要结合事务处理、完整性约束、错误处理和高级工具来实现。理解这些概念和实践方法对于构建高效、可靠的分布式系统是至关重要的。
数据库完整性的关注点在于数据的正确性、有效性和一致性。完整性约束分为值约束和结构约束两个方面,值约束涉及数据类型、格式、取值范围等,而结构约束则关注数据间的关系,包括函数依赖、实体完整性及参照完整性。...
以下是一些关于MySQL面试题、数据库操作、数据查询、数据库安全性和完整性的关键知识点,以及数据库编程的相关内容。 1. **MySQL面试题**: - 常见问题包括:SQL基本语法、JOIN操作、索引优化、事务处理、存储过程...
数据库事务是数据库管理系统(DBMS)中的一个基本概念,它将一系列操作作为一个工作单元执行,以确保数据的完整性和一致性。事务的ACID属性是确保数据库事务正确执行的四个关键特性:原子性(Atomicity)、一致性...
10. **数据库恢复技术**:当系统发生故障时,数据库恢复技术能够保证数据的完整性和一致性。实验可能涵盖日志文件的应用和检查点技术。 以上知识点是数据库课程实验可能涵盖的内容,通过这些实验,学生将获得数据库...
5. **事务处理与并发控制**:数据库中的事务处理是保证数据一致性和完整性的关键,报告可能涉及ACID属性(原子性、一致性、隔离性和持久性)以及锁机制。 6. **性能优化**:实验可能涉及到数据库性能的测试和优化,...
实验可能包括创建表、定义主键和外键、理解实体完整性、参照完整性和用户定义的完整性。 【SQL语言】 SQL(Structured Query Language)是用于管理关系数据库的标准语言,包括数据查询、数据操作、数据定义和数据...
通过上述方法和代码示例,我们可以看到在数据库中实现数据完整性的重要性和具体做法。实体完整性、域完整性、参照完整性以及用户定义的完整性共同作用,确保了数据的准确性和一致性。同时,事务的ACID特性为数据库...
总结来说,Oracle9i数据库的完整性和并发控制涉及到事务管理、ACID属性的实现以及并发操作的控制策略,如封锁机制。这些内容对于理解和操作大型数据库系统至关重要,确保了在高并发环境下数据的准确性和一致性。通过...
8. **第七章 - 第3节 - 数据库完整性.ppt**:这节可能涉及到实体完整性、参照完整性和用户定义的完整性,这些都是保证数据库数据准确无误的关键。 9. **第七章 - 第5节 - 并发控制.ppt**:在多用户环境下,如何处理...
3. **关系数据库**:由于关系模型是最常见的数据模型,因此试题会重点考察关系数据库的理论,如关系的定义、键(主键、外键)的概念、实体完整性、参照完整性和用户定义的完整性。 4. **数据库设计**:数据库设计...
6. 数据库完整性: 完整性规则确保数据库中的数据准确无误。实体完整性规定主键不能为NULL;参照完整性则涉及表间关联,保证引用的外键有效;用户定义的完整性根据具体业务规则设定。 7. 数据库安全性: 数据库...
理解如何设置用户权限,确保数据的隐私性和完整性,以及如何通过审计跟踪来检测潜在的安全威胁,是每个数据库管理员必备的知识。 接着,数据库原理与应用这部分内容可能涵盖关系模型、范式理论、数据库设计和优化。...
ACID属性(原子性、一致性、隔离性和持久性)是事务完整性的重要保障。 6. **约束**:SQL提供了多种类型的约束来维护数据完整性,如主键约束、外键约束、唯一约束、非空约束和检查约束。这些约束在数据插入、更新或...
7. **事务与并发控制**:事务是数据库操作的基本单元,具有ACID(原子性、一致性、隔离性和持久性)属性。并发控制则确保在多用户环境下,事务的执行不会相互影响,常见的并发控制技术有锁、两阶段提交和乐观并发...
2. 数据库管理员(DBA):DBA负责数据库的设计、实施、维护和性能优化,确保数据的安全性和完整性。 四、数据库设计 1. 需求分析:确定系统应存储的数据及其关联,以及对数据的操作需求。 2. 概念设计:使用ER...