Java教程

第三篇:事务

本文主要是介绍第三篇:事务,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

目录

 

数据库事务

事务模型

原子性 

一致性

隔离性 

持久性

磁盘写入以保持一致性

循环冗余校验 (CRC) 生成

使用 CRC 检查有效性

继续交易模型

FLAT 事务

嵌套事务

事务处理(TP)监视器

TP 监控服务

TP进程结构


数据库事务

事务 - 数据库中的工作单元
- 交易中可以包含任意数量和类型的操作
- 要么整体发生要么不发生
- 事务最好有四个属性,通常称为 ACID 属性

事务模型

ACID(原子性、一致性、隔离性、持久性)属性:

原子性 

对数据的所有更改都像单个操作一样执行。 即,执行所有更改,或者不执行任何更改。

示例 :

一笔交易 (i) 如果余额 >100,则减去 100 美元 (ii) 将 100 美元存入另一个账户

(两个动作要么一起发生,要么都不发生)

一致性

数据在交易开始和结束时处于“一致”状态——换句话说,写入数据库的任何数据必须根据所有定义的规则有效(例如,没有重复的学生 ID,没有负的资金转移, 等等。)

• 什么是“一致” - 取决于应用程序和上下文约束
• 一般不容易计算
• 只能保证受限类型的一致性,例如 可序列化的事务将在后面讨论。

隔离性 

事务被执行,就好像它是系统中唯一的事务一样。

• 例如,在将资金从一个帐户转移到另一个帐户的应用程序中,隔离可确保另一笔交易在一个帐户或另一个帐户中看到转移的资金,但不会在两个帐户中看到,也不在任何一个帐户中。

持久性

系统应该容忍系统故障,并且任何提交的更新都不应该丢失。

磁盘写入以保持一致性

要么整个块被正确写入磁盘,要么块的内容不变。 为了实现磁盘写入一致性,我们可以这样做 :

双工写

• 每个数据块顺序写入两个地方
• 如果其中一个写入失败,系统可以发出另一个写入
• 每个块都与一个版本号相关联。 具有最新版本号的块包含最新数据。
• 读取时 - 我们可以通过其 CRC(循环冗余校验后面讲) 来确定磁盘块的错误。
• 它始终保证至少一个块具有一致的数据。

记录写入 

类似于双工写入,除了其中一个写入到日志中。 如果对块的更改很小,则此方法非常有效。 我们将在本主题的后面讨论一种有效的方法。

循环冗余校验 (CRC) 生成

通信中或磁盘上的大多数错误都是连续发生的,这在本质上是突发的。 CRC生成器可以检测长度小于或等于32位的所有突发错误; 长度为 33 的 100 亿个突发错误中有 5 个将无法检测到; 100 亿个长度为 34 或更长的突发错误中有 3 个将无法检测到。

接下来举个例子吧

CRC多项式:x^{3}+ x + 1.

计算 n 位二进制 CRC:

1. 在输入位的右侧添加 n 个零位作为“填充”。

Input: 110100111

01100

11010011101100 000 <--- 输入左移 3 位填充,也就是在最右边填充3个0,为什么是3个,因为CRC多项式最高阶是3

2. 计算表示 CRC 除数的 (n + 1) 位模式(称为“多项式”)

在以下示例中,我们将使用 3 位 CRC 对 14 位消息进行编码,多项式为 x^{3} + x + 1。多项式以二进制形式写入系数; 三阶多项式有 4 个系数 (1*x^{3} + 0*x^{2} +1*x + 1)。 在这种情况下,系数为 1、0、1 和 1。

3. 将表示 CRC 除数的 (n + 1) 位模式放置在输入位的左侧下方。

11010011101100 000 <--- 输入右填充 3 位
1011 <--- 除数(4 位)= x³ + x + 1

4. 算法作用于每一步中除数正上方的位。

- 每次迭代的结果是多项式除数与其上方位的按位异或
- 不高于除数的位被简单地直接复制到该步骤的下方。
- 然后将除数右移一位(或移到被除数中的下一个 1 对齐),并重复该过程直到输入消息的位变为零。 以下是整个计算:

11010011101100 000 <--- 输入左移 3 位
1011 <--- 除数
01100011101100 000 <--- 结果
 1011 <--- 除数...
00111011101100 000
  1011
00010111101100 000
   1011
00000001101100 000
       1011
00000000110100 000
        1011
00000000011000 000
         1011
00000000001110 000
          1011
00000000000101 000
           101 1
-----------------
00000000000000 100 <---余数(3位)

除法算法在此停止,因为被除数为零。余数 100 将是 CRC 函数的值

使用 CRC 检查有效性

通过再次执行上述计算,可以很容易地验证接收到的消息的有效性,这次添加校验值而不是零。 如果没有可检测的错误,余数应为零。

11010011101100 100 <--- 输入CRC
1011 <--- 除数
01100011101100 100 <--- 结果
 1011 <--- 除数...
00111011101100 100
……
00000000001110 100
          1011
00000000000101 100
           101 1
------------------
0 <--- 余数

继续交易模型

动作类型
- 未受保护的操作 - 没有 ACID 属性
- 受保护的动作——这些动作在完全完成之前不会被外部化。 这些操作是受控的,如果需要可以回滚。 这些具有 ACID 属性。
- 真实动作 - 这些是一旦执行就无法撤消的真实物理动作。 在许多情况下,原子性在实际动作中是不可能的(例如,将两枚火箭作为单个原子动作发射)

FLAT 事务

BEGIN WORK 和 COMMIT WORK 中的所有内容都处于同一级别; 也就是说,事务要么与其他所有内容一起生存(提交),要么与其他所有内容一起回滚(中止)

限制

平面(FLAT)事务并没有为许多实际应用程序建模。

举个例子说明

机票预订
开始工作
S1:预订从墨尔本到新加坡的航班
S2:预订从新加坡飞往伦敦的航班
S3:预订从伦敦到都柏林的航班
结束工作

问题:从都柏林如果我们无法到达最终目的地,我们希望从新加坡飞往巴黎,然后到达我们的最终目的地。
如果我们回滚,我们需要重新预订从墨尔本到新加坡的机票,这是一种浪费。

也就是说,真实中这可能是一个运行时间很长的事务。 任何事务或交易失败都需要大量不必要的计算。

带保存点的平面事务可以缓解(这里不多讨论)

嵌套事务

规则

提交规则
- 子事务可以提交或中止,但是,除非父事务本身提交,否则无法进行提交。
- 子事务具有 A、C 和 I 属性,但没有 D 属性,除非其所有祖先都提交。
- 子事务的提交使其结果仅对其父事务可用。

回滚规则
如果事务回滚,则其所有子事务都将被迫回滚。

可见性规则
只有当子事务提交时,子事务所做的更改才对父事务可见。 父对象的所有对象对其子对象都是可见的。 这意味着当孩子正在访问对象时,父母不应修改对象。 这不是问题,因为父级不会与其子级并行运行。

事务处理(TP)监视器

TP 监视器的主要功能是集成其他系统组件和管理资源。

- TP 监视器管理客户端和服务器之间的数据传输
- 将应用程序或代码分解为事务并确保所有数据库都正确更新
- 如果发生任何错误,它也会采取适当的措施

TP 监控服务

异构性:如果应用程序需要访问不同的 DB 系统,单个 DB 系统的本地 ACID 属性是不够的。 本地 TP 监视器需要与其他 TP 监视器交互以确保整体 ACID 属性。 为此必须采用一种形式的 2 阶段提交协议(之后将讨论)。

控制通信:如果应用程序与其他远程进程通信,本地 TP 监视器应该维护进程之间的通信状态,以便能够从崩溃中恢复。

终端管理:由于许多终端运行客户端软件,因此 TP 监视器应在客户端和服务器进程之间提供适当的 ACID 属性。

演示服务:这类似于终端管理,因为它必须处理不同的演示(用户界面)软件——例如 X-windows

上下文管理:例如 维护会话等。

启动/重启:在基于 TP 的系统中启动和重启没有区别。

TP进程结构

术语
终端(客户端)希望应用服务器执行某些功能,而应用服务器又需要来自数据库的一些数据。
对于每个终端,都必须有一个进程,最终得到输入,理解函数请求,并确保函数得到执行(或执行函数本身)。

1、每个终端一个进程执行所有可能的请求,如下图

这个问题在于实在太昂贵了,终端一多的话。

2、一个进程执行所有终端的所有可能请求。

这种实现模型可能会出现以下问题:
调度导致的上下文切换会导致响应不佳;
单个大程序要处理各种终端。

3、多个通信进程和服务器

以上就是今天的关于事务的部分,后续还会继续深入讲解。辛苦大家观看,有问题随时评论交流哈,随时欢迎!

这篇关于第三篇:事务的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!