数据库并发控制
1.在数据库中为什么要并发控制 答数据库是共享资源,通常有许多个

新后的值,再按此新的 A 值进行运算。这样就不会丢失 T1 的更新。
T1
T2
①xlock A
获得
②读 A=16
③A← A← l 写回 A=15 Commit unlock A ④
⑤
XlockA 等待 等待 等待 等待 获得Ⅺock A 读 A=15 A→A 一 1 写回 A=14
Commit
Un loc kA DBMS 按照一定的封锁协议,对并发操作进行控制,使得多个并发操作有序地执行, 就可以避免丢失修改、不可重复读和读“脏”数据等数据不一致性。
t1t2xlocka获得读a16aal写回a15xlocka等待等待等待等待获得ocka读a15aa一1写回a14commitunlockacommitunlockadbms按照一定的封锁协议对并发操作进行控制使得多个并发操作有序地执行就可以避免丢失修改不可重复读和读脏数据等数据不一致性
1.在数据库中为什么要并发控制? 答 数据库是共享资源,通常有许多个事务同时在运行。 当多个事务并发 地存取数据 库时就会产生 同时读取和 /或修改同 一数据的情 况。若对
并发操作不加控制就可能会存取和存储不正确的数据,破坏数据库的一致性。所以数据库管 理系统必须提供并发控制机制。 2.并发操作可能会产生哪几类数据不一致?用什么方法能避免各种不一致的情况?
答: 并发操作带来的数据不一致性包括三类:丢失修改、不可重复读和读“脏”数 据。
(1)丢失修改(Lost Update) 两个事务 T。和 T2 读入同一数据并修改,T2 提交的结果破坏了(覆盖了)T。 提交的结果,导致 T1 的修改被丢失。 (2)不可重复读(Non—Repeatable Read) 不可重复读是指事务 T,读取数据后,事务 T2 孰行更新操作,使 T1 无法再现 前一次读取结果。不可重复读包括三种情况:详见《概论》8.1(P266)。 (3)读“脏”数据(Dirty Read) 读“脏”数据是指事务 T。修改某一数据,并将其写回磁盘,事务 T2 读取同一 数据后,T。由于某种原因被撤,这时 T。已修改过的数据恢复原值,T2 读到的 数据就与数据库中的数据不一致,则 T2 读到的数据就为“脏”数据,即不正确的 数据。 避免不一致性的方法和技术就是并发控制。最常用的技术是封锁技术。也可以用其他技 术,例如在分布式数据库系统中可以采用时间戳方法来进行并发控制。 3.什么是封锁? 答 封锁就是事务 T 在对某个数据对象例如表、记录等操作之前,先向系统发出 请求,对其加锁。加锁后事务 T 就对该数据对象有了一定的控制,在事务 T 释放 它的锁之前,其他的事务不能更新此数据对象。 封锁是实现并发控制的一个非常重要的技术。 4.基本的封锁类型有几种?试述它们的含义。 答 基本的封锁类型有两种:排它锁(Exclusive IJ0cks,简称 x 锁)和共享锁(Share Locks,简 称 S 锁)。 排它锁又称为写锁。若事务 T 对数据对象 A 加上 x 锁,则只允许 T 读取和修改 A,其 他任何事务都不能再对 A 加任何类型的锁,直到 T 释放 A 上的锁。这就保证了其他事务在 T 释放 A 上的锁之前不能再读取和修改 A。 共享锁又称为读锁。若事务 T 对数据对象 A 加上 S 锁,则事务 T 可以读 A 但不能修改 A,其他事务只能再对 A 加 S 锁,而不能加 x 锁,直到 T 释放 A 上的 s 锁。这就保证了其 他事务可以读 A,但在 T 释放 A 上的 S 锁之前不能对 A 做任何簸改。、 5.如何用封锁机制保证数据的一致性? 名 DBMS 在对数据进行读、写操作之前首先对该数据执行封锁操作,例如下图中事务 T1 在对 A 进行修改之前先对 A 执行 Xock(A),即对 A 加 x 锁。这样,当 T2 请求对 A 加 x 锁 时就被拒绝,T2 只能等待 T1 放 A 上的锁后才能获得对 A 的 x 锁,这时它读到的 A 是 T1 更
数据库事务的隔离级别与并发控制

数据库事务的隔离级别与并发控制在数据库管理系统中,事务的隔离级别和并发控制是确保数据完整性和一致性的重要手段。
隔离级别定义了事务之间的可见性,而并发控制则管理并发执行事务的方式。
本文将详细介绍数据库事务的隔离级别和并发控制。
一、事务的隔离级别1. 未提交读(Read Uncommitted)未提交读是最低的隔离级别,事务对其他事务所做的修改可以立即可见。
这会导致脏读(Dirty Read)问题,即读取到了尚未提交的数据,容易造成数据不一致。
2. 提交读(Read Committed)提交读是较低的隔离级别,事务只能读取已经提交的数据。
这避免了脏读,但可能会导致不可重复读(Non-Repeatable Read)问题,即在同一个事务中,两次读取同一个数据的结果不一致。
3. 可重复读(Repeatable Read)可重复读是较高的隔离级别,事务在执行期间多次读取同一个数据得到的结果是一致的。
这避免了脏读和不可重复读,但可能会导致幻读(Phantom Read)问题,即在同一个事务中多次执行相同的查询,结果集却发生了变化。
4. 串行化(Serializable)串行化是最高的隔离级别,事务串行执行,保证了数据的完全一致性。
但这会导致并发性能降低,因为每次只有一个事务能够同时执行。
二、并发控制的方法1. 锁机制锁机制是最基本的并发控制方法之一,通过给数据或资源加锁来实现对并发访问的控制。
常见的锁类型有共享锁和排它锁,共享锁允许多个事务并发读取数据,而排它锁则只允许一个事务独占访问数据。
2. 并发控制算法并发控制算法包括多版本并发控制(MVCC)、时间戳排序和两段锁协议等。
这些算法通过在数据中维护版本信息、时间戳或锁状态来实现事务的并发控制。
不同的算法适用于不同的场景,具体的选择需要根据实际需求和性能考虑。
3. 乐观并发控制乐观并发控制是一种无锁的并发控制方法,通过版本号或时间戳等机制来检测并发冲突并解决。
数据库并发控制的常见问题与解决方案

数据库并发控制的常见问题与解决方案数据库并发控制是数据库管理系统中一个重要的概念,它是指多个用户同时对数据库进行读取或写入操作时,保持数据一致性的技术手段。
在数据库系统中,可能会出现各种各样的并发控制问题,这些问题可能会导致数据异常或者系统性能下降。
本文将介绍数据库并发控制中常见的问题,并提供解决方案。
一、丢失更新问题丢失更新问题是指多个用户同时对同一数据进行写入操作时,可能会出现数据被意外地覆盖的情况。
这种问题通常发生在读-修改-写的操作之间,如果并发处理过程中没有适当的并发控制机制,多个写操作会互相覆盖,导致部分操作无法生效。
解决方案之一是使用事务来实现并发控制。
事务是一组数据库操作的逻辑单元,具有ACID特性。
通过使用事务,可以将一系列读操作和写操作包装在一起,以确保数据的一致性。
事务通过使用隔离级别,如读未提交、读提交和可重复读等,来解决丢失更新的问题。
二、脏读问题脏读问题是指一个事务读取了另一个事务尚未提交的数据。
当一个事务对数据进行更改时,另一个事务在读取这个数据之前将其更改给其他值,造成读取脏数据的情况。
为了解决脏读问题,可以采用对事务进行隔离的方式。
各种隔离级别,如读未提交、读提交、可重复读和串行化,提供了不同程度的并发控制和数据一致性。
通过设置适当的隔离级别,可以避免脏读问题。
三、不可重复读问题不可重复读问题是指在一个事务中多次读取同一数据时,得到的结果不一致。
导致这个问题的原因是在事务执行期间,另一个事务对数据进行了修改或删除。
为了解决不可重复读问题,可以采用使用锁、读提交或可重复读形式的隔离级别。
通过使用合适的隔离级别,可以保证在一个事务中多次读取同一数据时,得到的结果是一致的。
四、幻读问题幻读问题是指在同一个事务中多次查询同一表,得到结果集不一致的情况。
导致这个问题的原因是在事务期间,另一个事务插入了新的数据或删除了已存在的数据。
为了解决幻读问题,可以采用使用锁、可重复读或串行化隔离级别。
数据库并发控制例题

数据库并发控制例题摘要:一、数据库并发控制概述1.并发控制的目的2.并发控制的手段二、数据库并发控制的原理1.封锁技术2.时间序列控制3.乐观控制三、数据库并发控制的例题解析1.封锁技术例题2.时间序列控制例题3.乐观控制例题四、例题总结与展望正文:一、数据库并发控制概述在数据库系统中,为了提高系统的并发性能和事务处理能力,需要对多个事务同时访问共享数据进行控制,这就是数据库并发控制。
并发控制的主要目的是保证数据的一致性和完整性,防止数据冲突和脏读等现象。
实现并发控制的手段主要有封锁技术、时间序列控制和乐观控制等。
二、数据库并发控制的原理1.封锁技术:封锁技术是一种广泛应用于数据库并发控制的方法,通过对数据对象加锁来防止多个事务同时对同一数据进行修改,从而保证数据的一致性。
2.时间序列控制:时间序列控制是根据事务执行的时间顺序来控制并发访问。
该方法通过为事务分配优先级,按照优先级顺序执行事务,从而避免冲突。
3.乐观控制:乐观控制是一种基于事务提交前对数据所做的修改进行检测的方法。
事务在执行修改操作时,不加锁,而是在提交时检测是否与其他事务产生冲突,若检测到冲突,则回滚事务并重新执行。
三、数据库并发控制的例题解析1.封锁技术例题:假设一个数据库系统中有两个事务T1 和T2,T1 正在对数据A 进行修改,此时T2 也要对数据A 进行修改。
通过封锁技术,可以为数据A 加锁,使得T2 在T1 完成修改前无法对数据A 进行修改,从而避免冲突。
2.时间序列控制例题:假设一个数据库系统中有三个事务T1、T2 和T3,它们的优先级顺序为T1 > T2 > T3。
通过时间序列控制,可以按照优先级顺序执行事务,首先执行T1,然后执行T2,最后执行T3。
这样可以避免优先级较低的事务与优先级较高的事务产生冲突。
3.乐观控制例题:假设一个数据库系统中有两个事务T1 和T2,T1 正在对数据A 进行修改,此时T2 也要对数据A 进行修改。
数据库并发控制例题

数据库并发控制例题
当多个用户或事务同时访问和操作同一数据库时,可能会出现数据不一致的情况。
为了解决这个问题,需要进行并发控制。
下面是一个关于数据库并发控制的例题:
假设有一个银行系统,其中有多个用户同时进行存款和取款操作。
如果没有并发控制,可能会出现以下问题:
1.丢失修改:假设用户A正在向账户中存入1000元,但在提交之前,用户B查询到了这个账户余额为900元,并立即取出了500元。
如果此时用户A的存款操作先于用户B的取款操作完成,那么用户的账户余额就会变为1400元,而实际上应该为1400元。
2.不可重复读:假设用户A查询到了账户余额为1000元,但在进行一些操作后再次查询时,发现账户余额已经变为900元。
这可能是因为用户B在此期间进行了取款操作。
3.读“脏”数据:如果用户A正在进行取款操作,但还没有提交,此时用户B查询到了这个账户余额为1500元(实际上应该是1400元),并取出了500元。
如果用户A最终提交了取款操作,那么就会造成用户的账户被多扣除了500元。
为了避免这些问题,可以使用并发控制技术,例如锁机制和事务隔离级别等。
通过合理地设置锁和事务隔离级别,可以保证多个用户或事务对同一数据的访问和操作不会互相干扰,从而保持数据的一致性和完整性。
简述数据库的并发控制概念以及并发控制的主要方法

简述数据库的并发控制概念以及并发控制的主要方法数据库的并发控制是指在多个用户同时访问数据库的情况下,确保数据的一致性和完整性。
并发控制的主要目标是在保证数据库事务的正确执行的同时,提高数据库系统的并发性能。
并发控制的概念:并发控制是指对同一资源的访问是受到一定的控制,以确保数据库的一致性和完整性。
在数据库系统中,多个用户可以同时执行事务,而这些事务可能会对数据库中的数据进行读取和修改操作。
并发控制机制必须保证多个事务对数据库的并发执行不会导致数据的不一致性和冲突。
并发控制的主要方法:1.锁定机制:锁定是指在事务执行期间,对被访问的数据进行加锁,以防止其他事务对该数据进行修改。
锁定机制可以分为共享锁(用于读操作)和排他锁(用于写操作)。
当事务需要对一些数据项进行读取或修改时,需要先获取相应的锁。
如果资源已经被其他事务锁定,则当前事务需要等待资源释放后才能继续执行。
2.时间戳机制:时间戳是给每个事务分配的一个唯一的标识,用来标记事务的开始时间或提交时间。
事务执行期间,每个事务所访问的数据都会被标记上时间戳,以记录事务对数据的读取和修改操作。
在并发执行时,系统可以根据时间戳的顺序来判断事务的串行执行顺序,从而避免冲突和不一致性。
3.多版本并发控制(MVCC):MVCC是在每个数据项上维护多个版本的数据,每个事务执行时,可以根据事务的时间戳或版本号来读取对应的数据版本。
MVCC对读取操作不加锁,只对写操作加锁,从而提高了并发性能。
当一个事务需要修改一些数据时,会生成新的数据版本,并将新版本的指针指向旧版本,这样其他事务可以继续读取旧版本的数据,不会被阻塞。
4.乐观并发控制:乐观并发控制假设在事务提交时不会发生冲突,因此不对数据进行加锁。
当事务提交时,系统会检查该事务对数据修改时是否发生冲突。
如果没有冲突,该事务的修改操作会被接受,否则会被回滚,重新执行。
除了以上主要的并发控制方法,还有一些辅助的并发控制技术,如死锁检测和恢复、并发控制粒度的调整、多级锁技术等。
数据库锁与并发控制的调优方法与案例分享

数据库锁与并发控制的调优方法与案例分享随着互联网的不断发展和数据量的急剧增长,数据库在大型应用系统中起到了非常重要的作用。
然而,数据库的并发问题一直以来都是困扰开发人员和数据库管理员的难题。
在高并发环境下,数据库锁与并发控制的调优成为提升系统性能和稳定性的关键。
本文将介绍数据库锁与并发控制的基本概念,探讨一些常见的调优方法,并结合实际案例分享经验与技巧。
一、数据库锁与并发控制的基本概念在多用户环境中,当多个用户同时访问同一数据时,就会产生并发问题。
数据库锁与并发控制的主要目的是确保数据的一致性和完整性,以防止数据不一致和错误的更新。
下面是一些基本的数据库锁与并发控制的概念:1. 锁(Lock):在数据库中,锁是用来协调并发访问的一种机制。
它可以保护共享资源的完整性,防止读写冲突。
常见的锁包括共享锁和排他锁。
2. 共享锁(Shared Lock):共享锁又称为读锁,它允许多个用户同时读取一个共享资源,但不允许任何用户对该资源进行修改。
3. 排他锁(Exclusive Lock):排他锁又称为写锁,它只允许一个用户对资源进行排他性访问,其他用户无法同时读取或修改该资源。
4. 事务(Transaction):事务是由一个或多个数据库操作语句组成的逻辑工作单元。
它要么全部执行成功,要么全部失败,具有ACID特性(原子性、一致性、隔离性和持久性)。
5. 并发控制(Concurrency Control):并发控制是通过锁来实现数据一致性的机制。
它可以保证每次事务的执行都是基于一致性的数据,并避免并发事务之间的互相干扰。
二、数据库锁与并发控制的调优方法优化数据库锁与并发控制是提高系统性能和稳定性的关键步骤。
下面将介绍一些常见的调优方法:1. 合理设计数据库表结构:对于高并发环境下的数据库,合理的设计表结构是非常重要的。
可以通过合理划分表空间、选择合适的数据类型和长度,避免过度设计和冗余数据。
2. 正确选择锁的粒度:锁的粒度会影响数据库的并发性能。
数据库并发控制的主要方法

数据库并发控制的主要方法
数据库并发控制的主要方法包括以下几种:
1. 锁:数据库可以使用锁来避免多个事务同时访问同一数据。
当一个事务正在修改某个数据时,其他事务必须等待锁释放后才能访问该数据。
这种方式的优点是简单易用,但缺点是会延迟事务的执行。
2. 乐观锁:乐观锁是一种并发控制机制,它通过记录版本号来实现对数据的锁定。
当一个事务修改数据时,它将版本号设置为当前值,其他事务需要先查询数据的版本号,如果发现版本号不一致,则该事务将被阻塞,直到乐观锁被释放。
这种方式的优点是命中概率高,但需要额外维护版本号。
3. 序列化:序列化是一种高级的并发控制机制,它通过将所有事务的执行顺序执行同一个操作来实现高并发的控制。
当一个事务开始执行时,它需要等待其他所有事务都完成并释放锁,然后才能执行自己的操作。
这种方式的优点是可以保证数据的一致性,但需要更高的网络延迟和更高的开销。
4. 并发调度:数据库可以通过调整并发调度的策略来实现并发控制。
例如,数据库可以在多个事务同时执行时,优先处理较新的事务,以避免多个事务同时执行导致的数据不一致。
这种方式的优点是可以提高并发性能,但需要更高的编程技巧和经验。
在实际应用中,不同的方法需要根据具体情况进行选择。
例如,当并发量较低时,可以使用锁来控制并发,但当并发量较高时,序列化和并发调度可能更加有效。
此外,需要尽量避免使用单一的并发控制机制,以避免产生死锁等问题。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据库是一个共享资源,可以提供多个用户使用。
这些用户程序可以一个一个地串行执行,每个时刻只有一个用户程序运行,执行对数据库的存取,其他用户程序必须等到这个用户程序结束以后方能对数据库存取。
但是如果一个用户程序涉及大量数据的输入/输出交换,则数据库系统的大部分时间处于闲置状态。
因此,为了充分利用数据库资源,发挥数据库共享资源的特点,应该允许多个用户并行地存取数据库。
但这样就会产生多个用户程序并发存取同一数据的情况,若对并发操作不加控制就可能会存取和存储不正确的数据,破坏数据库的一致性,所以数据库管理系统必须提供并发控制机制。
并发控制机制的好坏是衡量一个数据库管理系统性能的重要标志之一。
DM用封锁机制来解决并发问题。
它可以保证任何时候都可以有多个正在运行的用户程序,但是所有用户程序都在彼此完全隔离的环境中运行。
一、并发控制的预备知识(一) 并发控制概述并发控制是以事务(transaction)为单位进行的。
1. 并发控制的单位――事务事务是数据库的逻辑工作单位,它是用户定义的一组操作序列。
一个事务可以是一组SQL 语句、一条SQL语句或整个程序。
事务的开始和结束都可以由用户显示的控制,如果用户没有显式地定义事务,则由数据库系统按缺省规定自动划分事务。
事务应该具有4种属性:原子性、一致性、隔离性和持久性。
(1)原子性事务的原子性保证事务包含的一组更新操作是原子不可分的,也就是说这些操作是一个整体,对数据库而言全做或者全不做,不能部分的完成。
这一性质即使在系统崩溃之后仍能得到保证,在系统崩溃之后将进行数据库恢复,用来恢复和撤销系统崩溃处于活动状态的事务对数据库的影响,从而保证事务的原子性。
系统对磁盘上的任何实际数据的修改之前都会将修改操作信息本身的信息记录到磁盘上。
当发生崩溃时,系统能根据这些操作记录当时该事务处于何种状态,以此确定是撤销该事务所做出的所有修改操作,还是将修改的操作重新执行。
(2)一致性一致性要求事务执行完成后,将数据库从一个一致状态转变到另一个一致状态。
它是一种以一致性规则为基础的逻辑属性,例如在转账的操作中,各账户金额必须平衡,这一条规则对于程序员而言是一个强制的规定,由此可见,一致性与原子性是密切相关的。
事务的一致性属性要求事务在并发执行的情况下事务的一致性仍然满足。
它在逻辑上不是独立的,它由事务的隔离性来表示。
(3)隔离性隔离性意味着一个事务的执行不能被其他事务干扰。
即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
它要求即使有多个事务并发执行,看上去每个成功事务按串行调度执行一样。
这一性质的另一种称法为可串行性,也就是说系统允许的任何交错操作调度等价于一个串行调度。
串行调度的意思是每次调度一个事务,在一个事务的所有操作没有结束之前,另外的事务操作不能开始。
由于性能原因,我们需要进行交错操作的调度,但我们也希望这些交错操作的调度的效果和某一个串行调度是一致的。
DM实现该机制是通过对事务的数据访问对象加适当的锁,从而排斥其他的事务对同一数据库对象的并发操作。
(4)持久性系统提供的持久性保证要求一旦事务提交,那么对数据库所做的修改将是持久的,无论发生何种机器和系统故障都不应该对其有任何影响。
例如,自动柜员机(ATM)在向客户支付一笔钱时,就不用担心丢失客户的取款记录。
事务的持久性保证事务对数据库的影响是持久的,即使系统崩溃。
正如在讲原子性时所提到的那样,系统通过做记录来提供这一保证。
DM没有提供显式定义事务开始的语句,第一个可执行的SQL语句(除CONNECT语句外)隐含事务的开始,但事务的结束可以由用户显式的控制。
在DM中以下几种情况都结束(正常,非正常)某一事务:(1)当某一连接的属性设置为自动提交,每执行一条语句都会提交;(2)遇到COMMIT/ROLLBACK语句,便提交/回滚一事务;(3)当系统的DDL自动提交开关打开时(缺省为打开),遇到DDL语句则自动提交该DDL语句和以前的DML和DDL操作;(4)事务所在的程序正常结束和用户退出;(5)系统非正常终止时;说明:DM在配置文件中提供了DDL语句的自动提交开关DDL_AUTO_COMMIT。
当此配置项的值为1(缺省情况)时,所有DDL语句自动提交;当此配置项的值为0时,除CREATEDATABASE、ALTERDATABASE和CREATESCHEMA语句外的所有DDL语句都不自动提交。
DM中的一致性是以事务为基础的。
DM通过提交和回滚分别用于将对数据库的修改永久化和废除,但是无论是提交和回滚,DM保证数据库在每个事务开始前、结束后是一致的。
为了提高事务管理的灵活性,DM提供了设置保存点(SAVEPOINT)语句和回滚到保存点语句。
保存点提供了一种灵活的回滚,事务在执行中可以回滚到某个保存点,在该保存点以前的操作有效,而以后的操作被回滚掉。
DM中的事务同样具有上述4个属性:原子性、一致性、隔离性和持久性。
2. 并发操作与数据的不一致性如果没有锁定且多个用户同时访问一个数据库,则当他们的事务同时使用相同的数据时可能会发生问题,导致数据库中的数据的不一致性。
一个最常见的并发操作的例子是火车/飞机订票系统中的订票操作。
例如,在该系统中的一个活动序列:①甲售票员读出某航班的机票张数余额A,设A=16;②乙售票员读出同一航班的机票张数余额A,也是16;③甲售票员卖出一张机票,修改机票张数余额A=A-1=15,把A写回数据库;④乙售票员也卖出一张机票,修改机票张数余额A=A-1=15,把A写回数据库。
结果明明卖出两张机票,数据库中机票余额只减少1。
这种情况称为数据库的不一致性。
这种不一致性是由甲、乙两个售票员并发操作引起的。
在并发操作情况下,对甲、乙两个事务操作序列的调度是随机的。
若按上面的调度序列行,甲事务的修改就被丢失。
这是由于第4步中乙事务修改A并写回覆盖了甲事务的修改。
并发操作带来的数据库不一致性可以分为四类:丢失或覆盖更新、脏读、不可重复读和幻像读,上例只是并发问题的一种。
<!--[if !supportLists]-->(1)<!--[endif]-->丢失或覆盖更新(lost update)当两个或多个事务选择同一数据,并且基于最初选定的值更新该数据时,会发生丢失更新问题。
每个事务都不知道其它事务的存在。
最后的更新将重写由其它事务所做的更新,这将导致数据丢失。
上面预定飞机票的例子就属于这种并发问题。
事务1与事务2先后读入同一数据A=16,事务1执行A-1,并将结果A=15写回,事务2执行A-1,并将结果A=15写回。
事务2提交的结果覆盖了事务1对数据库的修改,从而使事务1对数据库的修改丢失了。
(2)脏读一个事务读取了另一个未提交的并行事务写的数据。
当第二个事务选择其它事务正在更新的行时,会发生未确认的相关性问题。
第二个事务正在读取的数据还没有确认并且可能由更新此行的事务所更改。
换句话说,当事务1修改某一数据,并将其写回磁盘,事务2读取同一数据后,事务1由于某种原因被撤销,这时事务1已修改过的数据恢复原值,事务2读到的数据就与数据库中的数据不一致,是不正确的数据,称为脏读。
例如,在下图中,事务1将C值修改为200,事务2读到C为200,而事务1由于某种原因撤销,其修改作废,C恢复原值100,这时事务2读到的就是不正确的“脏“数据了。
(3)不可重复读(nonrepeatable read)一个事务重新读取前面读取过的数据,发现该数据已经被另一个已提交的事务修改过。
即事务1读取某一数据后,事务2对其做了修改,当事务1再次读数据时,得到的与第一次不同的值。
例如,在下图中,事务1读取B=100进行运算,事务2读取同一数据B,对其进行修改后将B=200写回数据库。
事务1为了对读取值校对重读B,B已为200,与第一次读取值不一致。
(4)幻像读如果一个事务在提交查询结果之前,另一个事务可以更改该结果,就会发生这种情况。
这句话也可以这样解释,事务1按一定条件从数据库中读取某些数据记录后未提交查询结果,事务2删除了其中部分记录,事务1再次按相同条件读取数据时,发现某些记录神秘地消失了;或者事务1按一定条件从数据库中读取某些数据记录后未提交查询结果,事务2插入了一些记录,当事务1再次按相同条件读取数据时,发现多了一些记录。
产生上述四类数据不一致性的主要原因是并发操作破坏了事务的隔离性。
并发控制就是要用正确的方式调度并发操作,使一个用户事务的执行不受其他事务的干扰,从而避免造成数据的不一致性。
3. 并发场景列举结合SQL语句,列举各种并发情况(包括可能导致数据不一致性和对数据一致性不产生影响的情况)。
A表示某一条数据,b和c都表示满足某一个标准的两条或多条数据,^表示“非”的意思,∈表示属于或包含于的意思,1表示第一个事务,2表示第二个事务。
(二) 并发操作的调度计算机系统对并行事务中并行操作的调度是随机的,而不同的调度可能会产生不同的结果,那么哪个结果是正确的,哪个是不正确的呢?如果一个事务运行过程中没有其他事务在同时运行,也就是说没有受到其他事务的干扰,那么就可能认为该事务的运行结果是正常的或者预想的,因此将所有事务串行起来的调度策略是正确的调度策略。
虽然以不同的顺序串行执行事务也可能会产生不同的结果,但由于不会将数据库置于不一致状态,所以都可以认为是正确的。
由此可以得到如下结论:几个事务的并行执行是正确的,当且仅当其结果与按某一次序串行地执行它们的结果相同。
我们称这种并行调度策略为可串行化(serializable)的调度。
可串行性(serializability)是并行事务正确性的唯一准则。
例如,现在有两个事务,分别包含下列操作:事务1:读B;A=B+1;写回A;事务2:读A;B=A+1;写回B;假设A的初值为10,B的初值为2。
下图给出了对这两个事务的三种不同的调度策略,(a)和(b)为两种不同的串行调度策略,虽然执行结果不同,但他们都是正确的调度。
(c)中两个事务是交错执行的,由于执行结果与(a)、(b)的结果都不同,所以是错误的调度。
(d)中的两个事务也是交错执行的,由于执行结果与串行调度1(图(a))的执行结果相同,所以是正确的调度。
为了保证并行操作的正确性,DBMS的并行控制机制必须提供一定的手段来保证调度是可串行化的。
从理论上讲,在某一事务执行时禁止其他事务执行的调度策略一定是可串行化的调度,这也是最简单的调度策略,但这种方法实际上是不可行的,因为它使用户不能充分共享数据库资源。
目前DBMS普遍采用封锁方法(悲观方法,DM采用的就是这种方法,SQL Server也是采用的这种方法)来保证调度的正确性;即保证并行操作调度的可串行性。