SSIS 你真的了解事务吗?
事务用于处理数据的一致性,事务的定义是,处于同一个事务中的操作是一个工作单元,要么全部执行成功,要么全部执行失败。把事务的概念应用到在实际的SSIS Package场景中,如何在Package中实现事务,事务的行为是什么样的,你真的了解吗?
SSIS默认支持Task组件级别的事务,在默认情况下,单个Task组件在开始执行时,会打开连接,开启一个事务,等到Task组件执行完成,提交事务,关闭连接,也就是说,默认情况下,单个Task组件在单个事务中执行查询,因此,在单个Execute SQL Task组件中执行大量的TSQL脚本,不是明智的选择,因为,这会导致日志文件的激增。如果Task组件执行失败,SSIS引擎自动进行回滚Task级别上的事务。如果在Task中使用begin tran命令开启一个显式事务,必须在组件中显式提交事务;当执行显式事务的组件失败时,组件会回滚显式事务。SSIS支持更复杂的事务处理,包括单一连接的本机事务,和跨连接的分布式事务处理。
一,SSIS支持的事务
在SSIS Package中,按照事务的分布性,可以把事务分为两种类型:
- 分布式事务:通过分布式事务协调器(DTC,Distributed Transaction Coordinator) 实现跨连接,Task和Package的事务处理;
- 本机事务:是SQL Server引擎级别事务,通过TSQL事务命令管理的单一连接的事务处理;
事务处理,都依赖连接管理器的支持。让Package使用本机事务的关键是所有的任务组件都使用相同的连接管理器,并且连接管理器(Connection Manager)上的属性RetainSameConnection设置为True:

让Package使用分布式事务的关键是所有的任务组件使用的连接管理器都支持DTC事务,并且连接管理器的SupportsDTCTransactions属性值都为True:

二,单个Task组件的事务处理
最常用的Task组件是Execute SQL Task组件,在该组件中执行的TSQL脚本处于同一个事务中。在该Task组件执行时,打开连接,开启一个事务,直到所有的TSQL脚本都成功执行,组件执行成功;一旦该Task中的某个TSQL脚本执行失败,事务回滚,这意味着,该Task中的所有已经执行的TSQL脚本都将回滚。因此,在单个Execute SQL Task组件中执行大量的TSQL脚本,不是明智的选择,因为,这会导致日志文件的激增。
创建测试表,测试表只有一列:
create table dbo.dt_test
(ID int)
在Execute SQL Task组件中执行以下语句:
insert into dbo.dt_test
values(1) insert into dbo.dt_test
values('a')
Task组件执行失败,从数据库中查看,测试表中没有插入任何数据,这说明,单个Task中的所有TSQL语句都包含在单个事务中。
三,本机事务处理(多Task组件,单一连接,单一事务)
在SSIS的任务和容器组件中,很多操作都需要连接到数据库执行查询,使用本机事务处理的关键是,所有的任务组件都使用相同的连接管理器,并且设置连接管理的属性RetainSameConnection为True,其默认值是False。
如果连接管理器的属性RetainSameConnection值是False,那么每个Task组件在开始执行时,打开连接,在组件结束时,关闭连接。在组件执行结束时,如果存在未提交的事务,那么组件会自动回滚Task组件的TSQL查询语句。由于每个组件都会打开和关闭连接,即使两个组件,使用的是同一个连接管理器,它们使用的连接都是不同的。
- 案例1:有两个组件,在一个组件中创建一个临时表或临时变量,在另一个组件中是不能使用的,这是因为在第一个组件结束时,连接也被关闭,临时表或临时变量的生命周期结束。
- 案例2:在循环任务中连接数据库时,设置RetainSameConnection值是True,能够避免频繁地打开/关闭连接。在Package开始执行时,打开连接,package结束时,关闭连接,保证所有task组件使用的都是同一个连接。
如果连接管理器的属性RetainSameConnection值是true,那么连接管理器会保持打开,直到Package结束,连接才会关闭。在连接关闭时,SSIS引擎会检查连接中是否存在未提交的事务,如果存在,执行事务回滚。
- 案例3:有两个组件,使用的是同一个连接管理器,属性RetainSameConnection值是true。在一个组件中创建一个临时表或临时变量,在另一个组件中可以使用,这是因为在第一个组件结束时,连接没有被关闭,两个组件使用的是同一个连接,临时表或临时变量的生命周期会持续到Package结束。
- 案例4:将连接管理器的属性RetainSameConnection设置为true,在上游组件中开启事务,在下游组件中提交事务,实现本机事务处理。
示例,利用TSQL命令(begin/commit/rollback tran)实现事务的提交或回滚
Package的设计如下图所示:

Exec TSQL组件执行的TSQL语句是:dbo.dt_test只有一列 ID,是int类型,该组件会执行失败。
insert into dbo.dt_test
values('a')
case1,设置连接管理器的RetainSameConnection属性值为False,rollback tran组件执行报错

从Progess选项卡中,查看Exec TSQL组件抛出的错误消息是:
insert into dbo..." failed with the following error: "Conversion failed when converting the varchar value 'a' to data type int.".
rollback tran 组件抛出的错误消息是:
[Execute SQL Task] Error: Executing the query "rollback tran" failed with the following error: "The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION.".
分析:由于连接管理器的属性RetainSameConnection为False,每个Task组件都是单独打开和关闭连接,begin tran组件已经把显式事务提交,rollback tran组件没有begin tran子句,无法执行事务回滚。
case2,设置连接管理器的RetainSameConnection属性值为True
1,设置连接管理器的RetainSameConnection属性值为True,rollback tran组件执行报错
把连接管理器的属性RetainSameConnection设置为True,使所有的Task组件使用的连接都是相同的。再次执行Package,还是失败,错误原因是:
[Execute SQL Task] Error: Executing the query "rollback tran" failed with the following error: "The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION.".

这是由于Execute SQL Task 在失败时,SSIS引擎自动进行事务的回滚。
这个结论可以通过增加一个Insert 1 组件来实现,向测试表中插入数值1,代码如下:
insert into dbo.dt_test
values(1)

在Exec TSQL组件上添加OnPostExecute断点,在Task执行之后,抛出错误之前,停止程序的运行:

重新执行Package,在执行到断点时,测试表已经插入的数值1 被删除,这说明,Exec TSQL组件的失败,会导致整个事务自动回滚。
结论1:当Execute SQL Task执行失败时,SSIS自动进行事务的回滚,但是当Execute SQL Task执行成功时,不会自动提交显式事务;开启一个显式事务,必须显式提交事务。
2,开启一个显式事务,需要显式提交事务
把Exec TSQL执行的语句修改插入数值2,这样,组件执行成功:
insert into dbo.dt_test
values(2)

如果把commit tran组件禁用,Package执行成功,但是测试表中没有插入任何数据,这说明,Package执行完成之后,连接管理器检测到有未提交的事务,自动把未提交的事务回滚。下图所示,事务并没有提交成功,而是被回滚。

结论2:开启一个显式事务,需要显式提交事务。当连接关闭时,SSIS会回滚未提交的显式事务。SSIS会检查每一个连接内是否存在未提交的显式事务,如果存在,那么回滚该事务;对于隐式事务,当TSQL语句执行结束时,会自动提交或回滚。
四,分布式事务处理(多Task组件,多连接,单一事务)
本机事务只能使用单一连接,在同一个连接中通过TSQL命令执行事务处理,不能实现跨连接,不能跨数据库的事务,由于SSIS经常需要处理多个数据库的数据,本机事务无法实现跨数据库的事务处理,用户可以通过MS DTC(微软分布式事务服务)实现分布式事务处理。
在SSIS 引擎服务器上启用MS DTC服务,并在Package的Task组件上设置相应的TransactionOption,就能使用分布式事务。
每个可执行组件(Task或Container)都包含Transactions属性组,SSIS通过这两个属性实现事务处理:
- IsoLationLevel:设置事务的隔离级别;
- TransactionOption:设置事务选项;
- Supported:如果已经存在一个事务,那么当前组件加入到事务中;
- Not Supported:即使存在一个事务,当前组件也不会加入到事务中;
- Requried:如果存在事务,那么当前组件加入到事务中;如果不存在事务,那么启动一个事务。
案例:两个Task,一个事务
在单一Package的不同Task组件中引用分布式事务,简化的设计如下图,两个Task组件使用不同的连接管理器:

设置Required组件的TransactionOption属性为Required,开启一个分布式事务处理:

设置Supported组件的TransactionOption属性为Supported,加入到当前的事务中,这就意味着,一个事务就包含两个Task,两个连接:

这样设置之后,在同一个Package的不同的Task组件中,一个跨连接的分布式事务处理建立完成。
分布式事务处理,还支持多Package,多连接,单一事务模式,不再赘述。
SSIS 你真的了解事务吗?的更多相关文章
- [转] SSIS可靠性和扩展性—事务
本文转自:http://www.cnblogs.com/tylerdonet/archive/2011/09/23/2186579.html 在这一个随笔中将介绍在package中如何使用事务来保证数 ...
- SSIS 事务
本文摘自:http://www.cnblogs.com/tylerdonet/archive/2011/09/23/2186579.html 在这一个随笔中将介绍在package中如何使用事务来保证数 ...
- SQL Server 中的事务与事务隔离级别以及如何理解脏读, 未提交读,不可重复读和幻读产生的过程和原因
原本打算写有关 SSIS Package 中的事务控制过程的,但是发现很多基本的概念还是需要有 SQL Server 事务和事务的隔离级别做基础铺垫.所以花了点时间,把 SQL Server 数据库中 ...
- SQL Server中的事务与其隔离级别之脏读, 未提交读,不可重复读和幻读
原本打算写有关 SSIS Package 中的事务控制过程的,但是发现很多基本的概念还是需要有 SQL Server 事务和事务的隔离级别做基础铺垫.所以花了点时间,把 SQL Server 数据库中 ...
- 写给小白看的Mysql事务
1 为什么需要事务 在网上的很多资料里,其实没有很好的解释为什么我们需要事务.其实我们去学习一个东西之前,还是应该了解清楚这个东西为什么有用,硬生生的去记住事务的ACID特性.各种隔离级别个人认为没有 ...
- 使用Connetion的属性RetainSameConnection
在SSIS的组件中,很多都会连接到数据库进行操作,Connection有一个属性RetainSameConnection,默认值是False,控制着连接的打开和关闭的时机. 1,如果Connectio ...
- MySQL 中隔离级别 RC 与 RR 的区别
1. 数据库事务ACID特性 数据库事务的4个特性: 原子性(Atomic): 事务中的多个操作,不可分割,要么都成功,要么都失败: All or Nothing. 一致性(Consistency): ...
- mysql rr和rc区别
<pre name="code" class="html">1. 数据库事务ACID特性 数据库事务的4个特性: 原子性(Atomic): 事务中的 ...
- 面试必问:ACID/CAP
转载: https://www.jdon.com/artichect/acid-cap.html ACID和CAP的详尽比较 事务机制ACID和CAP理论是数据管理和分布式系统中两个重要的概念,很不巧 ...
随机推荐
- windows7下搭建python环境并用pip安装networkx
1.安装顺序:Python+pip+pywin32+numpy+matplotlib+networkx 2.版本问题 所安装的所有程序和包都需要具有统一的python版本.系统版本和位宽,所以第一步要 ...
- jquery插件导出excel和pdf(解决中文乱码问题)
参考文件:http://jackyrong.iteye.com/blog/2169683 https://my.oschina.net/aruan/blog/418980 https://segmen ...
- js拼接table查询信息部分
其一: $("#datagrid").empty(); var a=0; <order-rows> a++; $("#datagrid").appe ...
- WebStorm 中 dva 项目用 start 命令需要不断重启项目问题
问题: 用dva-cli 构建的项目,用webstorm进行开发,通过 npm start进行启动,经常修改了文件之后,浏览器里面的内容没有刷新,需要重新执行npm start才行. 解决办法: we ...
- 【转】Linux 高级的视角来查看Linux引导过程
[原文]https://www.toutiao.com/i6594210975480545800/ 1.概述 图 1 是我们在20,000 英尺的高度看到的视图. 当系统首次引导时,或系统被重置时,处 ...
- redis 持久化与备份策略
持久化(persistence) 本文是 Redis 持久化文档 的中文翻译. 这篇文章提供了 Redis 持久化的技术性描述,推荐所有 Redis 用户阅读. 要更广泛地了解 Redis 持久化,以 ...
- python spawnv用法
test.py import os import string def run(program, *args): file = program result = os.spawnv(os.P_WAIT ...
- GoldenGate配置(三)之DDL复制配置
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/huangyanlong/article/details/33430293 GoldenGate配置( ...
- 死磕nginx系列--使用nginx做负载均衡
使用nginx做负载均衡的两大模块: upstream 定义负载节点池. location 模块 进行URL匹配. proxy模块 发送请求给upstream定义的节点池. upstream模块解读 ...
- 【转】使用Chrome Frame,彻底解决浏览器兼容问题
本文转自http://www.ryanbay.com/?p=269,感谢该作者的总结 X-UA-Compatible是自从IE8新加的一个设置,对于IE8以下的浏览器是不识别的. 通过在meta中设置 ...