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服务,可以停止。
位置:控制面板--管理工具--服务--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 回车,搞定!