ado.net 分布式事务处理示例,及微软官方示例

do.net事务处理的一个实例,画面就三个按钮开始事务,执行,提交事务

        TransactionScope trans;

        /// <summary>
        /// 事务开始按钮的处理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnOpen_Click(object sender, EventArgs e)
        {
            //只要在当前进程中声明 TransactionScope,那么关于DB的执行都会自动加入事务处理控制中
            trans = new TransactionScope(TransactionScopeOption.Required);
        }

        /// <summary>
        /// 事务执行内容
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnExcute_Click(object sender, EventArgs e)
        {
            string connstrA = "Data Source=localhost;Initial Catalog=TabA;Integrated Security=SSPI;";
            string connstrB = "Data Source=localhost;Initial Catalog=TabB;Integrated Security=SSPI;";

            SqlConnection connA = new SqlConnection(connstrA);
            SqlCommand commA = connA.CreateCommand();
            connA.Open();
            commA.CommandText = "DELETE FROM [TabA].[dbo].[TabA_USER] WHERE USER_ID = 'user001'";
            commA.ExecuteNonQuery();
            connA.Close();

            SqlConnection connB = new SqlConnection(connstrB);
            SqlCommand commB = connB.CreateCommand();
            connB.Open();
            commB.CommandText = "DELETE FROM [TabB].[dbo].[TabB_USER] WHERE USER_ID = 'user002'";
            commB.ExecuteNonQuery();         
            connB.Close();
            
        }

        /// <summary>
        /// 事务提交
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnComplete_Click(object sender, EventArgs e)
        {
            trans.Complete();
            trans.Dispose();
        }
    }

下面这段代码是微软的官方示例,很能说明问题,

注意分布式 事务处理如果遇到错误的时候,事务自动控制执行的内容进行回滚,不需要我们额外做类似于rollback之类的处理

        static public int CreateTransactionScope(
            string connectString1, string connectString2,
            string commandText1, string commandText2)
        {
            int returnValue = 0;
            System.IO.StringWriter writer = new System.IO.StringWriter();
            using (TransactionScope scope = new TransactionScope())
            {
                using (SqlConnection connection1 = new SqlConnection(connectString1))
                {
                    try
                    {
                        connection1.Open();

                        SqlCommand command1 = new SqlCommand(commandText1, connection1);
                        returnValue = command1.ExecuteNonQuery();
                        writer.WriteLine("Rows to be affected by command1: {0}", returnValue);

                        using (SqlConnection connection2 = new SqlConnection(connectString2))
                            try
                            {
                                connection2.Open();

                                returnValue = 0;
                                SqlCommand command2 = new SqlCommand(commandText2, connection2);
                                returnValue = command2.ExecuteNonQuery();
                                writer.WriteLine("Rows to be affected by command2: {0}", returnValue);
                            }
                            catch (Exception ex)
                            {
                                writer.WriteLine("returnValue for command2: {0}", returnValue);
                                writer.WriteLine("Exception Message2: {0}", ex.Message);
                            }
                    }
                    catch (Exception ex)
                    {
                        writer.WriteLine("returnValue for command1: {0}", returnValue);
                        writer.WriteLine("Exception Message1: {0}", ex.Message);
                    }
                }
                scope.Complete();
            }

            if (returnValue > 0)
            {
                writer.WriteLine("Transaction was committed.");
            }
            else
            {
                writer.WriteLine("Transaction rolled back.");
            }

            Console.WriteLine(writer.ToString());

            return returnValue;
        }
附:服务器xxx上的MSDTC不可用解决办法
MSDTC(分布式交易协调器),协调跨多个数据库、消息队列、文件系统等资源管理器的事务。该服务的进程名为Msdtc.exe,该进程调用系统Microsoft Personal Web Server和Microsoft SQL Server。该服务用于管理多个服务器 .
位置:控制面板--管理工具--服务--Distributed Transaction Coordinator
依存关系:Remote Procedure Call(RPC)和Security Accounts Manager 
建议:一般家用计算机涉及不到,除非你启用Message Queuing服务,可以停止。
解决办法: 
  1. 在windows控制面版-->管理工具-->服务-->Distributed Transaction Coordinator-->属性-->启动
  2.在CMD下运行"net start msdtc"开启服务后正常。

  注如果在第1步Distributed Transaction Coordinator 无法启动,则是因为丢失了日志文件,重新创建日志文件,再启动就行了。重新创建 MSDTC 日志,并重新启动服务的步骤如下:
  (1) 单击"开始",单击"运行",输入 cmd 后按"确定"。
  (2) 输入:msdtc -resetlog (注意运行此命令时,不要执行挂起的事务)
  (3) 最后输入:net start msdtc 回车,搞定!

 

posted @ 2012-09-17 23:29  ShenJH.NET  阅读(353)  评论(0编辑  收藏  举报