您好,欢迎访问全国教育考试教材网
商品分类

关于java数据库编程中,真正对事务进行控制的是

首先,事务是数据库系统的重要概念,理解这个概念是恰当开发与数据库交互的APP应用的前提。

但是,许多开发人员对事务的认识比较片面、肤浅,只是等同于ACID,通过数据了解数据库系统引入事务的真正动机、ACID对事务意味着什么,以及最重要的

最近在导师手下做了一个关于微服务和分散事务的课题项目,作为必要的前期准备,有必要加深对独立事务的认识,理解其实现原理。

本文基于我在集团内的伙伴共享的PPT进行修改,旨在帮助建立关于事务的相对体系的认识。

当时正好赶上考试周,所以写起来很着急。 里面一定有不理解和错误的地方。 我想让正在看的伙伴指出来。

有几点需要强调。

以下内容都是针对独立事务的,与分布式事务无关。 有关事务原理的说明没有针对具体的某个数据库实现,有些地方可能与你的实践经验不一致。

1 .事务1.1了解为什么需要数据库事务

转账是生活中的常见操作,如从A账户转账100元到B账户。

从用户的角度来看,这在逻辑上是一个操作,但在数据库系统中至少分为两个步骤

1 .减少a账户金额100元2 .增加b账户金额100元。

此过程可能会出现以下问题:

1 .转账操作第一步执行成功,A账户钱少100元,但第二步执行失败,或未执行过程中系统崩溃,B账户未相应增加100元。

2 .转账操作完成后立即发生系统崩溃,系统重新启动恢复时崩溃前的转账记录丢失。

3 .同时另一用户转账到B账户,同时操作B账户,导致B账户金额出现异常。

要解决这些问题,必须引入数据库事务的概念。

1.2什么是数据库事务

定义:数据库事务是组成单个逻辑工作单元的操作集合

典型的数据库事务如下

BEGIN TRANSACTION //事务开始SQL1SQL2COMMIT/ROLLBACK //事务的提交或回退事务的定义有几点需要说明。

1 .数据库事务可以包含一个或多个数据库操作,但这些操作构成整个逻辑。

2 .构成整个逻辑的这些数据库操作要么全部执行成功,要么全部不执行。

3 .构成事务的所有操作都不影响数据库,也就是说,无论事务是否成功,数据库始终保持一致。

4 .即使数据库发生故障且存在并发事务,以上内容也成立。

1.3事务如何解决问题

在上面的转移示例中,与转移相关的所有操作都可以包含在一个事务中

BEGIN TRANSACTION A账户减少100元b账户增加100元COMMIT1.如果数据库操作失败或系统崩溃,系统可以以事务为边界恢复,即使a账户金额减少,b账户也不会增加

2 .当多个用户同时操作数据库时,数据库以事务为单位进行同时控制,可以相互隔离多个用户向b账户的转账操作。

事务方便了系统的故障恢复和并发控制,保证了数据库状态的一致性。

1.4事务的ACID特性和实现原理综述

原子事务中的所有操作整体上都像原子一样不可分割,要么全部成功,要么全部失败。

一致性( Consistency ) :事务的执行结果必须将数据库从一个一致性状态移动到另一个一致性状态。

一致性状态是指:1.系统状态满足数据完整性约束(主控码、参考完整性、校验约束等)。2 .系统状态反应数据库应该描述的现实世界的实际情况,例如转账前后两个账户的金额总和应该是一定的

独立性( Isolation ) :同时执行的事务不会相互影响。 对数据库的影响与串行运行时相同。

例如,如果多个用户同时转账到一个账户,则最后一个账户的结果应该与他们按照优先顺序转账的结果相同。

提交持久性事务后,数据库更新将是持久性的。

事务或系统故障不会导致数据丢失。

在事务的ACID特性中,C即一致性是事务的根本追求,数据一致性的破坏主要来自两个方面

1 .事务并发2 .事务故障或系统故障数据库系统通过并发控制技术和日志恢复技术来避免这种情况。

并发控制技术保证了事务的可分离性,同时执行的操作不会破坏数据库的一致性状态。

日志恢复技术保证事务的原子性,并确保事务或系统故障不会破坏一致性状态。

此外,通过确保对提交的数据库所做的更改不会因系统崩溃而丢失,可以保证事务的持久性。

2 .并发异常和并发控制技术2.1常见并发异常

在说明并发控制技术之前,先简单介绍一下数据库中常见的并发异常。

脏写意味着事务已回滚了对数据项的已提交更改。 例如,在以下情况下,事务1中的数据a将回滚,事务2中已提交的更改也将回滚:

丢失更新的更新是指事务将复盖其他事务中对数据所提交的更改,使这些更改看起来像丢失了一样。

事务1和事务2都读取a的值为10,事务2首先将a加10并提出修正,然后事务2将a减10并提出修正,a的值为最后,事务2对a的修正为

脏读是一个事务读取另一个事务中未提交的数据。 在事务1对a的处理过程中,事务2读取了a的值,然后事务1回退,事务2读取的a将成为未提交的脏数据。

不可重复读取不可重复意味着一个事务对同一数据的读取结果前后不一致。

脏读和非可重复读之间的区别在于前者读取事务未提交的脏数据,后者读取事务提交的数据。 但是,前后两次读取的结果不同,因为其他事务已修改了数据。 例如,在以下情况下,事务1前后两次读取的结果不一致,因为对事务2的a的提交发生了更改:

幻读是指事务读取某个范围内的数据时,其他事务的操作导致前后两次读取结果不一致。

幻读与不可重复读取的区别在于,不可重复读取是针对特定行中的数据进行的,而幻读取是针对不确定的多行数据进行的。

因此,幻读通常出现在具有查询条件的范围查询中。 例如,如果事务1查询的数据为A5,而事务2插入的数据为A=4,则事务1查询的结果可能不同

2.2事务隔离级别

事务是可分离的,理论上事务之间的执行不应该相互影响,对数据库的影响应该与串行执行时相同。

但是,完全隔离会降低系统的并发性和资源利用率,实际上会降低对隔离的要求,从而在一定程度上降低对数据库完整性的要求,从而为事务定义不同的隔离级别。 从低到高,未提交的“读已提交”、已提交的“读已提交”、可重复的“读”和序列化“可序列化”故障

与各种隔离级别的并发异常的对应情况如下表所示。 必须强调的是,这种对应关系是理论性的,对于特定数据库(如mysql )的实现来说并不一定准确

的Innodb存储引擎使用Next-Key Locking技术,在可读级别消除了幻读的可能性。

事务的隔离级别不允许脏写。 序列化可以避免所有可能出现的并发异常,但会大大降低系统的并发能力。

2.3事务隔离的实现——常见并发控制技术

并发控制技术是实现事务隔离性和不同隔离级别的关键,实现方式有很多,根据对其可冲突操作的不同策略可分为乐观并发控制和悲观并发控制两种。

乐观控制:允许在实际发生冲突之前解决冲突,例如,假设同时执行潜在冲突的操作时实际上不存在冲突,然后回滚事务。

悲观同时控制:对于同时执行有可能发生冲突的操作,假定一定会发生冲突,通过让事务等待(锁定)或者中止(进行时间戳分类),使并行操作串行执行。

2.3.1基于封锁的并发控制

核心思想:对可能同时发生冲突的操作(如读-写、写-读、写-写),通过锁定互斥执行。

锁通常有两种类型:共享锁和独占锁

1 .共享锁( s ) :事务t对数据a施加共享锁,其他事务只能对a施加共享锁,但不能施加排他锁。

2 .排他锁( x ) :事务t对数据a施加排他锁,其他事务t对a既不施加共享锁也不施加排他锁的基于锁的并发控制过程:

事务将根据自己对数据项执行的操作类型申请合适的锁(共享锁的读取申请、排他锁的写入申请)的请求发送到锁管理器。

锁定管理器根据当前数据项是否已经具有锁定,以及申请的锁定和持有的锁定是否冲突,来决定是否向请求授予锁定。

如果授予了锁定,则申请锁定的事务可以继续执行。 如果被拒绝,则申请锁定的事务将等待,直到其他事务释放该锁定。

可能的问题:

死锁:如果多个事务持有锁,并且彼此循环等待其他事务的锁,则所有事务都将无法继续。

饥饿:事务无法获得a的独占锁,因为数据项a具有共享锁。

对于可能发生冲突的并发操作,通过锁定以并行方式串行执行是一种悲观的并发控制。

2.3.2基于时间戳的并发控制

核心思想:对于可能同时冲突的操作,根据时间戳排序规则选择某个事务继续执行,其他事务回退。

在每个事务开始时都会添加时间戳。 这个时间戳在系统时钟或者累积计数器值上,在回滚事务时给出新的时间戳,其中,初始事务的时间戳比稍后开始的事务的时间戳早

每个数据项q都有两个与时间戳相关的字段。

w-timestamp(q ) :成功执行所有写( q )事务的最大时间戳

r-timestamp(q ) :成功执行读( q )的所有事务的最大时间戳

时间戳的排序规则如下。

事务处理t发行read(Q ),假设t的时间戳为TSa .若TS(T

此读操作将被拒绝并回滚t。

b.ts(t )=W-timestamp(Q ) q )时,执行读操作,同时将r-timestamp ( q )设定为ts ) t )和r-timestamp ( q )的最大值,从而生成事务t

b .如果ts(t )是

c .其他情况:系统执行写操作,将w-timestamp(q )设置为ts ( t )。

基于时间戳的排序与基于锁的实现的本质相同。 可能发生冲突的并发操作是串行而不是并行执行的,因此也是悲观的并发控制。

区别主要有两个。

基于锁的是等待冲突的事务,而基于时间戳的排序是回滚冲突的事务。

基于锁争用事务的执行顺序是根据它们申请锁的顺序,先申请后执行; 基于时间戳的排序基于特定的时间戳排序规则。

2.3.3基于有效性检验的并发控制

核心思想:通过事务更新数据首先在自己的工作区进行,在回写到数据库之前进行有效性检查,回滚不符合要求的事务。

基于有效性检查的事务处理执行过程分为三个阶段:

读取阶段:读取数据项并将其保存在事务的局部变量中。

所有write操作都是对局部变量执行的,不会进行数据库的真正更新。

有效性检查阶段:对事务处理进行有效性检查,以确定是否可以在不违反序列化的情况下执行写操作。

如果失败,请回滚事务。

写入阶段:如果事务通过了有效性检查,则将临时变量的结果更新到数据库中。

有效性检查通常也通过比较事务的时间戳来进行,但与基于时间戳的排序规则不同。

通过这种方法,可以同时执行可能冲突的操作。 每个事务都处理自己工作区的局部变量,因此在有效性检查阶段检测到冲突之前不会回滚。

这是乐观的同时战略。

2.3.4基于快照隔离的并发控制

快照隔离是多级控制( mvcc )的实现方法。

其核心思想是,数据库为每个数据项维护多个版本(快照),每个事务只更新自己的专用快照,在事务实际提交之前进行有效性检查,从而实现事务

由于快照隔离会使事务无法识别其他事务对数据项的更新,因此可以使用以下两种方法避免更新丢失:

先提交者获胜:对于执行了该检查的事务t,判断其他事务是否已经向数据库写入了更新,如果没有则进行t回滚,否则t正常提交。

先更新者获胜:锁定机制可确保第一个获得锁定的事务提交更新,然后尝试更新的事务将中止。

事务之间可能存在冲突的操作由数据项的不同版本的快照分离,在实际写入数据库之前不会发生冲突检测。

这也是乐观的同时控制。

2.3.5并发控制技术总结

以上只是介绍了几种常见的并发控制技术,并不涉及特别复杂的原理说明。

这要真正明确原理和实现细节,需要的东西太多,篇幅太长,从作者和读者的角度来看不是一件容易的事情,所以我只简单介绍了其实现的核心思想和实现要点,其他部分都有。

二是并发控制的实现方式太多,基于块的实现有很多变体,mvcc多版本并发控制的实现方式更为多样,多与块方式等其他并发控制方式组合使用。

3 .故障与故障恢复技术3.1为什么需要故障恢复技术

数据库运行时可能会出现故障。 这些故障分为两类:事务故障和系统故障

事务故障:例如输入错误、系统死锁或事务无法继续。

系统故障:例如由于软件漏洞或硬件错误导致系统崩溃或中止。

由于这些故障可能会破坏事务和数据库的状态,因此必须提供恢复各种故障并确保数据库一致性、事务原子性和持久性的技术。

数据库通常将数据库操作记录为日志,并在出现故障时进行恢复,因此称为日志恢复技术。

3.2事务的执行过程和可能出现的问题

事务的执行过程可以简化为:

系统会在每次事务时打开专用工作区的事务读取操作,将数据从磁盘复制到工作区,然后在执行写入操作之前,所有更新都会影响工作区的副本。 事务写入操作将数据输出到内存缓冲区,并在经过适当的时间后由缓冲区管理器将数据写入磁盘。

由于数据库中存在即时更改和延迟更改,因此在事务执行过程中可能会出现以下情况:

在提交事务之前出现故障,但事务对数据库所做的某些更改已写入磁盘数据库。

这破坏了事务的原子性。

事务在系统崩溃之前已提交,但数据仍在内存缓冲区中且未写入磁盘。

此次提交的更改将在系统还原时丢失。

这是对事务持续性的破坏。

3.3日志类型和格式

说明对数据库的写入。 t是要写入的事务的唯一标识符,x是要写入的数据项,V1是数据项的旧值,V2是数据项的新值。

对数据库的写入操作的撤消操作,将事务t的x数据项恢复为旧值V1。

在事务恢复阶段插入。

:事务t开始:事务t提交:事务t中止日志有以下两个规则

1 .在对数据库进行更改之前,会将相应的日志记录添加到日志文件的末尾。

2 .事务的commit日志记录成功写入磁盘后,事务称已提交,但事务所做的更改可能未写入磁盘3.4日志恢复的核心思想

还原事务处理:将事务处理更新的所有数据项恢复为日志中的旧值,并在事务处理还原完成时插入记录。

重做事务处理:将事务处理更新的所有数据项恢复为日志中的新值。

如果事务成功回滚/因事务故障而中止,则会进行重做

在系统从崩溃中恢复时,执行重做,然后执行还原。

以下事务将被还原: 日志只包含记录,不包含记录也不包含记录。

以下事务将被重做: 日志包括记录,也包括记录或记录。

假设系统从崩溃中恢复时的日志记录如下

由于T0同时包含开始记录和提交记录,因此请重做事务T0并执行相应的重做操作。

因为T1只有start记录,所以撤销T1,执行相应的还原操作,并在撤销完成后写入abort记录。

3.5事务故障中止/成功回滚恢复过程

从后向前扫描日志,并将事务t中每个表单中的记录的旧值V1写入数据项x。

在日志中写入特殊的只读记录,指示将数据项恢复为旧值V1。 这是只读补偿记录,不需要还原。

找到日志记录后,停止继续扫描并将日志记录写入日志。

3.6系统崩溃时的恢复过程(带检查点) ) ) ) ) ) )。

检查点是一种特殊的日志记录,其中l是写入检查点记录时未提交的事务的集合,在检查点之前提交的事务对数据库的更改已写入磁盘

检查点可以加快恢复过程。

系统崩溃时的恢复过程分为重做阶段和撤销阶段两个阶段。

重做阶段:

将从最后一个检查点开始向前扫描日志,并将要重试的事务列表undo-list设置为检查点日志中的l列表。

如果找到的更新记录或的补偿取消记录,请重试该操作。

找到记录后,将t添加到还原列表中。

或者找到记录后,从undo-list中删除t。

撤销阶段:

系统从末尾开始反向扫描日志以发现属于还原列表的事务的日志记录,执行还原操作以发现还原列表中事务的t条记录,然后将其写入记录,将t写入还原列表

4 .如果还原列表为空,则撤消阶段结束

摘要:按顺序重做所有记录的事务处理更新,并对需要撤消的事务处理按相反顺序执行撤消更新操作。

3.6.1系统崩溃恢复示例

恢复前日志如下所示,写入最后一个日志记录后,系统崩溃

//以前T2已经commit,所以不重新进行//T0回滚就完成,插入该记录后系统就会崩溃4 .总事务是数据库系统进行并发控制的基本单位,数据库进行并发控制

ACID是事务的基本特性,数据库系统通过并发控制技术和日志恢复技术保证事务的ACID,可以得到如下有关数据库事务的概念架构。