从Oracle事务到Oracle分布式事务- 2021-12-23

数据库事务是使用Oracle经常会遇到的一个问题,实际的开发工作中对于数据库事务的应用是比较多的,那么对事务的熟悉也经常会成为面试的一个考点之一。可以测试一下开发人员的基本功以及数据库的掌握深度。下面我们要说一下Oracle相关的事务了。

1.事务概要

事务是不可分割的一系列数据库操作,这些操作要么整体成功,要么整体失败。 事务维护数据完成性,保证数据库在一个一致性状态。

事务可以看成是一个独立的逻辑单元,由一系列整体成功或失败的SQL语句组成。

2.Oracle事务

事务的四个基本特性ACID,原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。

  • 原子性:整个操作必须被完成或者终止,不能部分完成。
  • 一致性:事务把资源从一个一致性状态带到另一个一致性状态。
  • 隔离性:事务在提交前,一个事务相对与另一个事务是不可见的。
  • 持久性:提交后的事务改变是永久的,就算系统重启或者失败都是可以恢复的。

2.1 事务隔离级别

SQL标准定义了四个隔离级别,分别是未提交读(Read Uncommitted)、提交读(Read Committed)、可重复读(Repeatable Read)、串行(Serializable)。以上4个隔离级别对应的并发性能逐次变差。

事务并发访问书库库是存在幻读,不可重复读,脏读等问题

  • 幻读:例如事务T1读取数据的数量或者排序结果,返回结果集。此时事务T2插入一条新纪录并Commit,此时事务1再次查询的时候其结果集可以看到事务T2插入的记录。即两次读取的数据集数量不同
  • 不可重复读:事务T1读取一行记录,紧接着事务T2修改了刚刚的记录并提交,T1再次查询发现与刚才插入的数据不同。即两次读取的同一行数据不同
  • 脏读:事务T1更新了一条记录,暂时未提交,T2读取了跟新后的数据,然后T1回滚了刚才的操作,此时T2读取的数据是无效的,即脏数据。即读取了无效的数据

隔离级别对应可能产生的问题

隔离层 脏读 不可重复读 幻读
Read Uncommitted
Read Committed
Repeatable Read
Serializable

Oracle数据库支持的隔离级别如下提交读(Read Committed)、串行(Serializable)、只读(Read Only),其并发性逐次降低。

默认情况下,Oracle中的事务在其他用户提交工作之后马上会允许读取,即Read Committed。所以默认情况下可能会发生不可重复读或幻读,而且不可能发生脏读。

2.2 开始和结束事务

Oracle数据库中,事务时从会话的第一个DML操作开始,直到遇到commit或者rollback结束。这是一个事务,之后再开启一个DML操作,则会开始一个新的事务,

3. Oracle分布式事务

在分布式数据库环境下,我们的事务对象横跨多个数据库对象。为了保证ACID的事务基本特性,从而有了分布式事务的概念。

我们这里说的是Oracle的分布式事务。如果是通过其他中间件来实现分布式事务,这里先不讨论。

Oracle分布式事务中有几个概念。

  • Local Coordinator 分布式事务中,必须参考其他节点上的数据才能完成自己的操作的站点。
  • Global Coordinator 分布式事务的发起者,负责协调这个分布式事务。
  • Commit Point Site 在分布式事务中,首先执行COMMIT或rollback的站点。

Oracle分布式事务一般分3个提交过程。

  1. 准备阶段
    • 本地数据库向其他数据库发出COMMIT通知
    • 比较所有数据库的SCN号,以最高的SCN号作为全局SCN号
    • 所有数据库在线写日志
    • 对分布事务修改的表加分布锁,防止被读写
    • 各个数据库向本地数据库发出已经准备好的通知
  2. 提交阶段
    • 本地数据库通知commit point site首先提交。commit point site提交后,释放其占有的资源,通知Global Coordinator完成提交
    • 本地数据库Global Coordinator通知其他数据库提交
    • 提交节点在日志中追加一条信息,表示事务已经提交,并通知Global Coordinator。此时所有数据库的数据保持了一致性。
  3. 注销阶段
    • 本地和数据库通知commit point site所有数据库已经完成提交
    • commit point site清楚分布事务的记录和状态信息,并通知Global Coordinator
    • Global Coordinator清楚本地分布事务的记录和状态信息

此时分布式事务两阶段提交全部完成。

总结

事务在日常开发中使用非常多,自然都是我们的学习的重点。事务使用时也会有许多的坑,那么我们后面也会介绍一下事务使用过程中踩过的坑。尽情期待吧!

Java Geek Tech wechat
欢迎订阅 Java 技术指北,这里分享关于 Java 的一切。