MS SQL Server:事务处理概念和 MS DTC 概述 (简述)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MS SQL Server:事务处理概念和 MS DTC 概述 (简述)相关的知识,希望对你有一定的参考价值。

参考技术A   引言    编写应用程序是很难的 随着时间的推移 我们不断发掘允许建立大型应用程序的概念和技术 模块化 或者说将应用程序构建成独立的模块 使我们得以由简单的部分构建复杂的系统 并使软件得到重复使用 面向对象概念和 Microsoft® 组件对象模块 () 可提供编写模块化应用程序的技术     当某个应用程序构建为组件时 各个单独部分可共同驻留在单台计算机上 也可通过远程过程调用在网络上相互作用 因此 组件同时提供了模块化和自然分布     将应用程序构建成独立的组件会产生组件的管理问题 单个程序失败后 将作为一个单位重新启动 但在使用模块化系统时 一个组件的失败不应当破坏其它组件 这就必须有隔离故障和限制故障传播的方法 事务提供了模块化执行方式 因此简化了故障处理 并使故障处理自动实现 它们同时为执行者和用户提供了简单的概念化执行框架     用户认为事务是单个的要么发生或要么不发生的更改事件 执行者认为事务是一种允许他们编写能参与分布式计算的模块的编程形式 假定您要将资金从一个银行帐户转到另一个帐户 执行者和用户需要确保两个帐户都更改或都不更改 在分布式系统中很难完成这项工作 计算机可能失败 并且会丢失信息 事务提供了一种方法 能够将一组操作集合成具有原子性的执行单位     原子性要么全有要么全无的属性并不新鲜 它在生活中随处可见 例如 如果输入一个合同 escrow(由第三者保存附带条件委付盖印的契约)官员将协调这项事务 escrow 官员会收集此合同每一方的签字 当 escrow 官员宣布所有人都已签字后 此合同就完成了 主持结婚典礼的牧师先问新娘和新郎 愿意此人成为您的配偶吗? 如果他们都回答 愿意 牧师就会宣布他们结婚 电影导演在某一场景会先问 布景准备好了吗? 如果都回答已准备好 导演就会喊 开拍! 在帆船上预备掉转航向的舵手会先问船员 准备好转向了吗? 如果都回答已准备好 舵手就会喊 转舵! 改变船的方向     这些情景说明了事务的基本原理 几个独立的实体必须达成一致 如果任何一方不同意 交易就会失败 一旦同意后 事务就会发生 Microsoft Distributed Transaction Coordinator (MS® DTC) 为 结构的其它组件执行这项事务协调任务     在 MS DTC 术语中 执行者被称为事务管理器 在执行事务保护资源的事务中 其参与者(如关系数据库)被称为资源管理器     应用程序通过调用事务管理器的 BeginTransaction 方法开始事务 这样可创建一个代表事务的事务对象 然后应用程序会调用资源管理器来完成事务工作     应用程序对每个资源管理器的第一次调用确定应用程序的当前事务 例如 如果应用程序在使用关系数据库 它会调用 ODBC 接口 此接口将事务对象与 ODBC 连接关联起来 在此之后 所有通过此连接的数据库调用都会代表该事务执行 直到该事务结束为止     当某个资源管理器首先代表某个事务工作时 会通过调用事务管理器 登记 到该事务中 随着事务的发展 事务管理器会跟踪每个登记到该事务中的资源管理器     通常 应用程序用 Commit 事务方法来完成事务 如果应用程序无法完成 则调用 Abort 事务方法 该方法可以撤消事务的操作 如果应用程序失败 MS DTC 就会放弃此事务     当应用程序成功地完成事务的工作后 它会调用 MS DTC 来 提交 事务 然后 MS DTC 会仔细检查 两阶段 提交协议 使所有已登记的资源管理器都提交 两阶段提交协议可确保所有的资源管理器提交此事务 或全都放弃此事务 在第一阶段 MS DTC 询问每个资源管理器是否 准备 提交 如果所有参与者都回答 是 那么在第二阶段 MS DTC 将向所有参与者广播提交信息 如果事务的任何部分失败 或资源管理器响应准备请求失败 或资源管理器响应 否 那么 MS DTC 将通知所有资源管理器该事务已被放弃     事务管理器是大多数数据库系统的关键部分 事务管理器还是某些操作系统的可选部分 Microsoft 相信事务对分布式应用至关重要 事务提供了模块化执行 从而使 模块化编程更加完备 Microsoft 提供 Microsoft Windows® 和 Microsoft Windows NT® 操作系统的事务管理软件     将事务概念与 必需的创新相结合 传统的事务系统要求具有很高的安装和管理技巧 而集成 MS DTC 与 Microsoft 操作系统的难点是自动实现安装 管理和使用 许多概念和技术必须针对新的客户/服务器 面向对象和可视化管理环境重新创造     在第一版中 MS DTC 使用了一个资源管理器 Microsoft SQL Server® 它还使用了几个事务处理监视器 包括 Encina® Top End 和 TUXEDO® MS DTC 实现 OLE 事务接口 所有 OLE 事务接口都是公用的 因此任何资源管理器都可以变成 OLE 事务资源管理器 将来 Microsoft 和其它软件公司将增加其它事务资源管理器 比如分布式对象系统 事务文件系统 事务队列系统及业务流程管理系统 lishixinzhi/Article/program/SQLServer/201311/22019

SQL Server错误严重性级别和异常处理

关于SQL Server的错误严重性级别的说明,强烈认真看一下下面的两个链接

脱机帮助

ms-help://MS.SQLCC.v9/MS.SQLSVR.v9.zh-CHS/sqlerrm9/html/3e7f5925-6edd-42e1-bf17-f7deb03993a7.htm

在线帮助

http://technet.microsoft.com/zh-cn/library/ms164086.aspx

简而言之,SQL Server的错误严重性分为三个等级

1. 轻微错误 :严重性级别为0-10

2. 中等错误 :严重性级别为11-19

3. 严重错误 :严重性级别为20-25

SQL Server保存的所有错误消息是可以通过检索sys.messages这个视图来查看的,如下

image

为什么需要说这个呢?是因为我们需要知道不同的错误严重性级别所导致的行为是不一样的

1. 轻微错误 :严重性级别为0-10  ==》默认情况下不会给客户程序发送错误消息,继续工作。也就是说它无法被CATCH到

2. 中等错误 :严重性级别为11-19 ==》能够被CATCH到(不管是在T-SQL里面还是在客户程序里面)

3. 严重错误 :严重性级别为20-25 ==》SQL Server将强制把连接关掉。很显然这也不可能被CATCH到

 

关于在T-SQL中使用TRY...CATCH处理异常,请参考下面的链接

http://technet.microsoft.com/zh-cn/library/ms179296.aspx

 

关于在客户端程序中处理异常,分两种情况

1. 对于错误严重性级别在11-19之间的,能够被TRY...CATCH到SQLException类型,然后可以对其进行处理

http://msdn.microsoft.com/zh-cn/library/system.data.sqlclient.sqlexception(VS.80).aspx

2. 对于错误严重性级别在0-10之间的系统错误,或者通过PRINT语句发出的消息,或者通过RAISERROR语句发出的错误,如果需要在客户程序里面处理,那么应该编写Connection对象的InfoMessage事件

http://msdn.microsoft.com/zh-tw/library/a0hee08w.aspx

关于infoMessage事件,因为它可以接受PRINT语句的输出消息,所以也有朋友用它来跟踪存储过程的进度等等,下面就有一个范例

http://www.cnblogs.com/hackzai/archive/2005/04/07/133635.html

还有一个属性很有意思,FireInfoMessageEventOnUserErrors 。这个属性为true,那么除了0-10的会被该事件处理,11-19的也可以通过该事件来处理,而不需要用TRY...CATCH

http://msdn.microsoft.com/zh-tw/library/system.data.sqlclient.sqlconnection.fireinfomessageeventonusererrors.aspx

下面是一个例子

private void btTest_Click(object sender, EventArgs e)
{
    using (SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["Northwind"].ConnectionString))
    {
       conn.FireInfoMessageEventOnUserErrors = true;
        conn.InfoMessage += new SqlInfoMessageEventHandler(conn_InfoMessage);
        SqlCommand cmd = conn.CreateCommand();
        cmd.CommandText = "DROP TABLE TABLE1"; //这里我是故意让它出错,因为表不存在。由于前面设置了FireInfoMessageEventOnUserErrors为true,所以会自动由infoMessage事件处理
        conn.Open();
        cmd.ExecuteNonQuery();
        cmd.CommandText = "RAISERROR(\'This is the message from the RAISERROR statement\', 10, 1)";
        cmd.ExecuteNonQuery();
        conn.Close();
    }

}

void conn_InfoMessage(object sender, SqlInfoMessageEventArgs e)
{
    MessageBox.Show(string.Format("Source:{0},Message:{1}", e.Source, e.Message));
}

值得注意的是,不管是SQLException还是InfoMessage中的事件参数SqlInfoMessageEventArgs,它们都包含一个Errors的集合,里面包含了所有的错误实例。一个完善的异常处理,应该遍历它们。例如下面这样

public static void ShowSqlException(string connectionString)
{
    string queryString = "EXECUTE NonExistantStoredProcedure";
    StringBuilder errorMessages = new StringBuilder();
    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        SqlCommand command = new SqlCommand(queryString, connection);
        try
        {
            command.Connection.Open();
            command.ExecuteNonQuery();
        }
        catch (SqlException ex)
        {
            for (int i = 0; i < ex.Errors.Count; i++)
            {
                errorMessages.Append("Index #" + i + "\\n" +
                    "Message: " + ex.Errors[i].Message + "\\n" +
                    "LineNumber: " + ex.Errors[i].LineNumber + "\\n" +
                    "Source: " + ex.Errors[i].Source + "\\n" +
                    "Procedure: " + ex.Errors[i].Procedure + "\\n");
            }
            Console.WriteLine(errorMessages.ToString());
        }
    }
}  

以上是关于MS SQL Server:事务处理概念和 MS DTC 概述 (简述)的主要内容,如果未能解决你的问题,请参考以下文章

将 MS Access 查询(使用 IIF() 和 DATESERIAL())事务处理到 T-SQL

在 MS Access 和 SQL Server 中处理图片

重新定义 MS Access 文件和 SQL Server 之间的数据链接

SQL Server错误严重性级别和异常处理

MS SQL Server 2008 中的空值处理

CREATE VIEW 必须是批处理 MS SQL Server 中的唯一语句