MS SQL Server和Oracle对数据库事务处理的差异性

本文涉及的产品
云数据库 RDS SQL Server,基础系列 2核4GB
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
日志服务 SLS,月写入数据量 50GB 1个月
简介:

背景

吉日嘎拉软件编程走火入魔之:数据库事务处理入门(适合初学者阅读)文章中关于MS SQL Server和Oracle对数据库事务处理的差异性引起一些争论,因此记录我对数据库事务处理的想法。

 

简介

本文讲述MS SQL Server和Oracle对数据库事务处理的差异性,以及Oracle如何对事务处理的实现。

 

什么是事务

数据库事务(Database Transaction)是一组数据库操作的处理单元。事务符合ACID的特性:

Atomic:原子性,要么全部要么一无所有。All or None.

Consistent:一致性,所有依赖关系以及约束一致。

Isolated:分离性,不同事务不互相影响。

Durable:持久性,提交事务的数据需要持久化。

 

为什么要使用事务

实现事务主要有两大功能:

1.保证数据库的consistent(一致性状态),保持所有依赖关系以及约束一致)。哪怕数据库管理系统出现故障时(例如断电),也能恢复到一致性状态。例如一个银行转帐系统,张三给李四转3000圆RMB,张三帐号上减3000和李四帐号上加3000需要同时完成,否则系统的帐就不平了。也例如有些销售系统的汇总表和明细表,是一个主表和一个从表,需要同步更新。

2.并发时分离不同事务操作。例如编辑过程中的数据不给其他事务查询到。这也是相对的,在特效需求下可能要支持dirty read(脏读),但不是这里讨论的范围了。

 

SQL Server 2008 的事务类型

1.自动提交事务 Autocommit Transactions

这是SQL Server默认的事务类型,每一条单独的SQL语句(SQL statement)都是单独的一个事务,语句执行完毕后自动提交。调用方不需要手工控制事务流程。

2.显示事务 Explicit Transactions

调用方需要调用API或者使用T-SQL的BEGIN TRANSACTION 语句来打开事务。需要调用COMMIT 或者 ROLLBACK TRANSACTION 来提交或者回滚。

3.隐式事务 Implicit Transactions

使用SET IMPLICIT_TRANSACTIONS ON把事务模式变成隐式模式。调用方不需要执行BEGIN TRANSACTION 语句来打开事务。数据库引擎执行到SQL语句的时候自动打开事务。调用方需要调用COMMIT 或者 ROLLBACK TRANSACTION 来提交或者回滚。当数据库引擎执行下一个SQL语句时又自动打开一个新事务。

参考:Controlling Transactions (Database Engine)

 

Oracle的事务类型

Oracle的事务处理类型有点像SQL Server的隐式事务。当执行到第一个可执行的SQL语句时自动打开事务,然后需要调用方执行commit或者rollback来提交或者回滚事务,如果有DDL语句,Oracle也会自动提交事务的。

参考:Transaction Management

 

Oracle的事务的实现

Oracle的结构分逻辑上和物理上的区别。逻辑上的结构是表空间,而物理上的结构是数据文件。

逻辑实现

Oracle下实现事务在逻辑上是由Undo Tablespace来实现的。Undo Tablespace包含Undo Segements(段),而Undo Segements包含Undo Data。Undo Data是支持事务的逻辑单元。

transaction2

图源自于《Oracle Database 10g: Administration Workshop I》

Undo Data用于保存修改前后的数据,以支持回滚,长时间查询,和flashback查询,以及失败事务恢复的功能。

由于有了Undo Data,回滚事务变得容易了,因为Undo Data保存了修改前后的数据,保证了事务的原子性。失败事务恢复和事务回滚类似,当网络中断或者其他原因导致事务异常停止,数据库引擎可以恢复到一致性状态。

同时Undo Data也支持长时间查询(Read-consistent),例如有表格T,主键为key,有字段为f1,数据如下,尽管只有4条数据,假设需要很长时间进行查询。

key

f1

1 A
2 B
3 C
4 D

事务一开始查询,一直没结束,而事务二开始修改key为1的数据为Z,事务二进行提交,数据变成下面的表格。但是事务一查询结束的时候还是读出A,B,C,D,因为查询是从Undo中读出快照。

key

f1

1 Z
2 B
3 C
4 D

Flashback查询是Oracle 10g引进的功能,可以查询出提交之后修改之前的数据,例如上面例子事务三在事务二提交后想查询出A,B,C,D可以通过Flashback查询来完成。这也是有Undo Data来支持的。

 

物理实现

从上面的逻辑实现看,只是知道了事务以及Undo Data的作用,还不清楚Oracle对事务的支持到底怎么实现的。下面从物理结构上讲述Oracle怎么对事务进行支持。请先看一个物理结构图。

transaction1 

图源自于《Oracle Database 10g: Administration Workshop I》

为了简化,我只是用个人的语言讲述和事务有关的部件。SGA可以理解为全局内存。其中Database Buffer Cache存放的是从数据文件中读取的数据缓存。紫色的圆柱体为数据文件。Redo Log Buffer为重做日志缓存,也就是保存日志的内存块,一切的数据的修改都会记录在Redo Log Buffer里面。例如用回事务二更新key为1数据的例子。当事务二更新key为1数据从A到Z。Oracle数据库引擎会把key为1的数据的rowid,修改前数据A以及修改后数据Z都记录在Redo Log Buffer里面。如果事务二继续更新key为2的数据为Y,那么key为2的数据的rowid,修改前数据B以及修改后数据Y也记录到Redo Log Buffer里面。每一笔数据都记录,而且是流水线性记录。一旦事务二进行提交,LGWR进程(Log Writer,日志写进程)就会把Redo Log Buffer的数据按顺序写到Log Datafile里面,也就是日志数据文件里面,当写日志文件完成,Oracle数据库引擎会生成一个SCN(system change number,系统更新号),到这时候Oracle数据库引擎会通知调用方提交完成了。这里可以看到Oracle在提交的时候不必要把更新数据写回数据文件,而是写到日志文件里面。因为顺序写线性的日志文件速度快很多,而写数据文件是需要随机读写。由于线性记录和SCN号控制,数据库引擎可以通过redo log(重做日志文件)的操作得到最新的数据。当然在Checkpoint的时候数据文件是最终还是会更新的,只是说事务提交的时候更新数据文件不是必须步骤,这样能很大的提高性能。

由于这个机制,回滚变得很简单,要读没提交前之前的SCN是很容易的事情。

 

对于初学者关于数据库事务处理的建议

我自己也是从新手一步步走过来,现在也不是老鸟,算是有点经验,如果是刚入门的同学,你觉得有用就看一下,没用就过了。

对于数据库事务的处理,开始的时候不需要很深入了解数据库的原理,当然以后还是需要了解的,优先级排后而已。高优先级如下:

首先,事务不是什么高深神秘的东西,我从入行开始所做的所有系统,包括现在的嵌入式系统,都用到事务。我并不觉得大部分系统事务有什么问题,只是一些约束和同步机制,真的有问题从自身系统设计角度看,不一定说从数据库技术角度去找解决方法。例如Oracle的长时间查询如果Undo Data(历史数据)给覆盖了,Oracle会抛出异常"ORA-01555: snapshot too old”,如果出现这种问题,我会从自身系统设计角度入手,为什么有那么大的查询,为什么在这个查询中其他事务会更新数据,这些查询是否只是查一次就够了,查的过程是否需要锁住表等等。然而这个问题可以通过数据库调优解决,但是我想问题的角度首先是从自身系统设计出发。

第二,要知道的是不同数据库的事务类型的区别,例如MS SQL Sever是默认是自动提交事务,用的时候需要知道每个语句都有单独的事务在操作。而Oracle是类似于隐式事务,必须手工commit或者rollback。

第三,使用事务要知道一一对应,特别是嵌套事务的时候,有始有终。很多问题时候发生终的时候,注意异常处理需要结束已经打开的事务。

 

第一点是心理问题,第二三点是技术问题,做好我觉得就可以入门开发系统了。以后碰到问题在一步步深入。

 

MS SQL Server对事务的实现下一篇再讲了。上述是我对Oracle实现的理解,有不当之处也希望指出,我可以完善文章。



    本文转自Jake Lin博客园博客,原文链接:http://www.cnblogs.com/procoder/archive/2009/10/06/1578346.html,如需转载请自行联系原作者


相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情: https://www.aliyun.com/product/rds/sqlserver
相关文章
|
3月前
|
SQL NoSQL 关系型数据库
实时数仓Hologres发展问题之实时数仓的类数据库化与HTAP数据库的差异如何解决
实时数仓Hologres发展问题之实时数仓的类数据库化与HTAP数据库的差异如何解决
52 2
|
3月前
|
Cloud Native 数据管理 数据挖掘
核心系统转型问题之阿里云数据库用户需求的通用性和差异性如何平衡
核心系统转型问题之阿里云数据库用户需求的通用性和差异性如何平衡
|
19天前
|
Oracle 安全 关系型数据库
Oracle与GreatSQL差异:更改唯一索引列
【11月更文挑战第1天】本文介绍了在 Oracle 和 GreatSQL 中更改唯一索引列的方法及差异。Oracle 需要手动删除和重建索引,过程复杂且可能影响数据一致性;而 GreatSQL 可以自动维护索引,直接修改列值即可,操作简便且更安全。
|
3天前
|
SQL Oracle 关系型数据库
Oracle与GreatSQL差异:更改唯一索引列
【11月更文挑战第11天】本文介绍了在 Oracle 和 GreatSQL 中修改唯一索引列的操作。Oracle 需要先删除索引、修改列值,再重新创建索引,步骤较为繁琐。而 GreatSQL 在满足一定条件下支持在线 DDL 操作,可以直接修改列值,操作相对简单。两者都需要考虑数据完整性和表上的其他约束条件。
|
2月前
|
关系型数据库 MySQL 网络安全
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
|
3月前
|
存储 SQL 分布式数据库
|
3月前
|
SQL 关系型数据库 MySQL
SQL Server、MySQL、PostgreSQL:主流数据库SQL语法异同比较——深入探讨数据类型、分页查询、表创建与数据插入、函数和索引等关键语法差异,为跨数据库开发提供实用指导
【8月更文挑战第31天】SQL Server、MySQL和PostgreSQL是当今最流行的关系型数据库管理系统,均使用SQL作为查询语言,但在语法和功能实现上存在差异。本文将比较它们在数据类型、分页查询、创建和插入数据以及函数和索引等方面的异同,帮助开发者更好地理解和使用这些数据库。尽管它们共用SQL语言,但每个系统都有独特的语法规则,了解这些差异有助于提升开发效率和项目成功率。
360 0
|
3月前
|
SQL 数据库 开发者
SQL事务处理与并发控制:保障数据一致性的关键——深入探索ACID原则、锁定与乐观并发控制策略,以及高级事务管理技巧
【8月更文挑战第31天】在数据库管理和应用开发中,确保数据一致性至关重要。SQL事务处理和并发控制是实现这一目标的关键技术,它们保证了多用户同时访问和修改数据时数据库的一致性和准确性。事务处理遵循ACID原则(原子性、一致性、隔离性和持久性),并发控制则通过锁定和乐观并发控制等策略管理多用户访问,防止数据冲突。本文将深入探讨这些技术的原理与应用,帮助开发者更好地保护数据。
50 0
|
3月前
|
SQL 数据处理 数据库
SQL进阶之路:深入解析数据更新与删除技巧——掌握批量操作、条件筛选、子查询和事务处理,提升数据库维护效率与准确性
【8月更文挑战第31天】在数据库管理和应用开发中,数据的更新和删除至关重要,直接影响数据准确性、一致性和性能。本文通过具体案例,深入解析SQL中的高级更新(UPDATE)和删除(DELETE)技巧,包括批量更新、基于条件的删除以及使用子查询和事务处理复杂场景等,帮助读者提升数据处理能力。掌握这些技巧能够有效提高数据库性能并确保数据一致性。
78 0
|
4月前
|
SQL 存储 监控
SQL Server的并行实施如何优化?
【7月更文挑战第23天】SQL Server的并行实施如何优化?
110 13

推荐镜像

更多