数据库

国产数据库与Oracle数据库事务差异分析

2025-04-17 16:10:00 | 来源:企业IT培训

数据库中的ACID是事务的基本特性,而在Oracle等数据库迁移到国产数据库国产中,可能因为不同数据库事务处理机制的不同,在迁移后的业务逻辑处理上存在差异。本文简要介绍了事务的ACID属性、事务的隔离级别、回滚机制和超时机制,并总结SAVEPOINT的使用,以总结。

1、数据库中事务基本概念

事务是数据库中的基本逻辑操作单元,由一组不可分割的数据库操作序列组成,这些操作要么全部成功执行,要么全部失败回滚。其核心目的是确保数据的完整性和一致性,尤其在并发操作或系统故障时维护数据库的可靠状态。

1.1 事务基本属性

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

原子性:事务中的所有操作必须作为一个整体执行,要么全部执行成功、要么全部失败回滚,不允许出现部分成功的情况。在数据库中通常是通过日志记录(如undo log)来实现回滚操作,若事务执行失败,系统跟进日志撤销已执行的操作。

一致性:事务执行前后,数据库必须保持一致性状态。所有数据必须满足预定义的完整性约束(如主键、外键、唯一性约束等)。即使事务失败,数据库也不能破坏这些规则。在数据库中通过一些约束和检查来确保数据库的完整性约束。

隔离性:多个事务并发执行时,每个事务的操作应与其他事务相互隔离,使得每个事务感觉不到其他事务的存在,最终效果应与事务串行执行的结果一致。数据库中通过锁机制(Locking)或多版本并发控制(MVCC)实现,不同的隔离级别提供不同程度的隔离性。

持久性:事务一旦提交,其对数据库的修改就是永久性的,即使系统发生故障(如断电、崩溃),修改也不会丢失。数据库中通过重做日志(Redo Log)实现持久性。提交事务时,对数据的修改首先写入日志,再异步写入数据库文件中。当数据库崩溃恢复时,通过重放日志恢复数据。

以转账交易为例,通过undo日志实现原子性,确保“扣款”和“存款”两个操作要么全部成功,要么全部失败;一致性是确保转账前后,数据库必须满足业务规则(如余额不为负、总额不变);通过锁机制和MVCC多版本并发控制来实现事务的隔离性,多个并发转账操作互不干扰,结果与串行执行一致;持久性则是一旦转账成功,即使系统崩溃,修改也不会丢失。

1.2 事务回滚机制

事务的原子性要求事务要么全部执行成功、要么全部执行失败回滚,但是对于Oracle数据库支持语句级的原子性,也就是一个事务中单个语句执行失败,则只会回滚该语句执行的操作,不会导致在当前事务中丢失之前的任何工作。如果需要回滚整个事务,需要处理错误并且主动调用ROLLBACK。这种语句级的回滚对于处理一些长时间运行的批处理任务有用,逻辑上希望能够处理错误,不需要回滚已经完成的所有操作。

1.3 事务超时机制

数据库中事务会设置不同的超时机制,防止因为出现等锁而出现无限等待,超过这个时间后会出现等锁超时,事务会回滚。

Oracle数据库:默认不会主动终止因行锁等待而阻塞的事务,事务会无限期等待锁释放,需由应用层处理或手动终止,行锁在事务提交或回滚是自动释放;事务默认也无超时设置,但是可以限制会话的空闲时间,超过时间后会断开链接。

MySQL数据库:通过 innodb_lock_wait_timeout 控制,默认为50秒。当事务等待锁超过此时间时,会抛出错误;事务中无默认超时时间,但是连接的空闲超时设置wait_timeout,默认8小时。

PostgreSQL:通过pg_lock_timeout设置行锁等待超时时间,默认为0无限等待;事务中设置statement_timeout 控制单条SQL执行时间,默认无限制。

TiDB:兼容MySQL行锁等待设置;如果是悲观事务,默认TTL(Time-To-Live)为 1小时,超时后自动回滚,另外通过tidb_idle_transaction_timeout 控制空闲事务。

OceanBase:MySQL模式下兼容MySQL设置;事务中通过 ob_query_timeout 控制事务单条语句执行时间,默认1800s

GoldenDB:兼容MySQL设置

GaussDB:参数lockwait_timeout控制单个锁的最长等待时间,当申请的锁等待时间超过设定值时,系统会报错,默认为20min;通过通过 statement_timeout 控制单个语句执行时长,默认0表示不控制。