事务用于处理数据的一致性,事务的定义是,处于同一个事务中的操作是一个工作单元,要么全部执行成功,要么全部执行失败。把事务的概念应用到在实际的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,多连接,单一事务模式,不再赘述。

使用Connetion的属性RetainSameConnection的更多相关文章

  1. SSIS 你真的了解事务吗?

    事务用于处理数据的一致性,事务的定义是,处于同一个事务中的操作是一个工作单元,要么全部执行成功,要么全部执行失败.把事务的概念应用到在实际的SSIS Package场景中,如何在Package中实现事 ...

  2. jqu

    1 /*2 * 说明:3 * 本源代码的中文注释乃Auscarlin呕心沥血所作.旨在促进jQuery的传播以及向广大jQuery爱好者提供一个进阶4 *的途径,以让各位更加深入地了解jQuery,学 ...

  3. [转]SSIS高级转换任务—在Package中是用临时表是需要设置RetainSameConnection属性

    本文转自:http://www.cnblogs.com/tylerdonet/archive/2011/05/20/2052306.html 在上一个导入列这个例子中我们创建一个实际的表来存储文件路径 ...

  4. js-静态、原型、实例属性

    本篇来说一下js中的属性: 1.静态属性 2.原型属性 3.实例属性 静态属性: function klass(){} var obj=new klass(); klass.count=0; klas ...

  5. 探究@property申明对象属性时copy与strong的区别

    一.问题来源 一直没有搞清楚NSString.NSArray.NSDictionary--属性描述关键字copy和strong的区别,看别人的项目中属性定义有的用copy,有的用strong.自己在开 ...

  6. CSS HTML元素布局及Display属性

    本篇文章主要介绍HTML的内联元素.块级元素的分类与布局,以及dispaly属性对布局的影响. 目录 1. HTML 元素分类:介绍内联元素.块级元素的分类. 2. HTML 元素布局:介绍内联元素. ...

  7. CSS float 浮动属性

    本篇主要介绍float属性:定义元素朝哪个方向浮动. 目录: 1. 页面布局方式:介绍文档流.浮动层以及float属性. 2. float:left :介绍float为 left 时的布局方式. 3. ...

  8. CSS Position 定位属性

    本篇文章主要介绍元素的Position属性,此属性可以设置元素在页面的定位方式. 目录 1. 介绍 position:介绍position的值以及辅助属性. 2. position 定位方式:介绍po ...

  9. npm package.json属性详解

    概述 本文档是自己看官方文档的理解+翻译,内容是package.json配置里边的属性含义.package.json必须是一个严格的json文件,而不仅仅是js里边的一个对象.其中很多属性可以通过np ...

随机推荐

  1. what is a ear

    http://docs.oracle.com/javaee/6/tutorial/doc/bnaby.html An EAR file (see Figure 1-6) contains Java E ...

  2. shell学习

    set -x 进入调试模式,会把每一个命令实际执行的命令打印出来,也就是会把一些参数扩展后的样子打印出来. set +x 退出调试模式自定义变量:x=7,y=8echo `expr $x + $y` ...

  3. 查找当前目录和所有子目录下的后缀名为.o的文件,删除之

    查找: find . -name "*.o" -exec ls {} \; 删除: find . -name "*.o" -exec rm -f {} \;

  4. 【随记】Hello World小记

    今天装Python,如下: 突然想到,到现在,我已经数不清写过多少遍Hello World了. 最早是初一学VB的时候,用Label1在Form1上画一个,然后修改Caption属性为“Hello W ...

  5. 使用属性android:onClick,出现异常NoSuchMethodException

    在Activity中注册点击事件有两种方式,setOnClickListener或在xml中设置控件的android:onClick="gotoSecond"属性,在Activit ...

  6. Android 向系统日历中添加事件

    查了一天半,总算有点大概了.以下是自己的理解,有错误的地方望指正. android系统有日历功能,应用程序可以根据一些接口开发自己的功能,即使是日历app也是根据这些接口开发的,所以我们可以利用程序向 ...

  7. CSS 禁止浏览器滚动条的方法(转)

    1.完全隐藏 在<boby>里加入scroll="no",可隐藏滚动条: <boby scroll="no"> 这个我用的时候完全没效果 ...

  8. Enum是如何用的?

    一.前言 对于枚举Enum,大家都非常熟悉,但枚举出现的场景非常多的时候,是不是可以抽象出一个通用的解决方式.代码大家都会写,但并不是所有人都喜欢写重复的代码,老是用Ctrl+C和Ctrl+V累不累啊 ...

  9. 深入理解openstack网络架构(1)

    原文地址: https://blogs.oracle.com/ronen/entry/diving_into_openstack_network_architecture 译文转载自:http://b ...

  10. Python黑客编程基础3网络数据监听和过滤

    网络数据监听和过滤 课程的实验环境如下: •      操作系统:kali Linux 2.0 •      编程工具:Wing IDE •      Python版本:2.7.9 •      涉及 ...