最近查看了一些在.NET环境下实现分布式事务处理的资料。
这里利用一个例子来说明利用COM+在.NET中实现分布式事务处理
首先,微软.NET的CLR替代了COM,但不会替代COM+,因为在.NET中,像分布式事务处理,对象池等技术的实现还依赖于COM+。COM+在.NET中又叫做企业服务。
开发环境:两台PC,运行Windows,SQL Server
例子:每次同时向两台PC中的SQL Server 2000中提交数据,如果出现任何异常,双方同时回滚。
具体过程:
1.在vs.net建立一个类库的项目,命名为BankComponentServ
2.编写源文件。注意,任何需要使用COM+服务的类都必须继承自System.EnterpriseService.ServiceComponent。
using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.OracleClient;
using System.EnterpriseServices;
using System.Runtime.CompilerServices;
using System.Reflection;
// Supply the COM+ application name.成功注册之后,在"控制面板->管理工具->组件服务"中,将可以看到以BankComponent命名的COM+服务
[assembly: ApplicationName("BankComponent")]
// Supply a strong-named assembly.生成强名称,后面说明
[assembly: AssemblyKeyFileAttribute("..\..\BankComponent.snk")]
// the ApplicationActivation.ActivationOption attribute specifies
// where assembly components are loaded on activation
// Library : components run in the creator's process
// Server : components run in a system process, dllhost.exe
[assembly: ApplicationActivation(ActivationOption.Library)]
namespace BankComponentServ
{
[Transaction(TransactionOption.Required)] //此处声明改类需要事务支持
///
/// Account 的摘要说明。
///
public class Account : ServicedComponent
{
private static int i = 0;
[AutoComplete] //声明为自动完成事务
public void post(){
string SqlServerConnection = "server=localhost;Trusted_Connection=false;database=TXDemoDB;User=sa;password=sa";
string SqlServerConnection1 = "server=LYQ-F95AC0E9CB5;Trusted_Connection=false;database=TXDemoDB;User=sa;password=sa";
String sql = "insert into currentValue (ID,currentValue) values ("+i+","+i+")";
SqlConnection sqlConn = new SqlConnection(SqlServerConnection);
SqlCommand sqlCommand = new SqlCommand(sql,sqlConn);
sqlConn.Open();
sqlCommand.ExecuteNonQuery();
sqlConn.Close();
SqlConnection sqlConn1 = new SqlConnection(SqlServerConnection1);
SqlCommand sqlCommand1 = new SqlCommand(sql,sqlConn1);
sqlConn1.Open();
sqlCommand1.ExecuteNonQuery();
sqlConn1.Close();
i++;
}
[AutoComplete] //声明为自动完成事务
public void post1(){
string SqlServerConnection = "server=localhost;Trusted_Connection=false;database=TXDemoDB;User=sa;password=sqladmin";
string SqlServerConnection1 = "server=LYQ-F95AC0E9CB5;Trusted_Connection=false;database=TXDemoDB;User=sa;password=sql";
string OracleConnection = "data source=sunv880;user id=solaris;password=solarisadmin";
SqlConnection sqlConn = new SqlConnection(SqlServerConnection);
SqlCommand sqlCommand = new SqlCommand("insert into currentValue (ID,currentValue) values (" + i +"," +i + ")",sqlConn);
sqlConn.Open();
sqlCommand.ExecuteNonQuery();
sqlConn.Close();
SqlConnection sqlConn1 = new SqlConnection(SqlServerConnection1);
SqlCommand sqlCommand1 = new SqlCommand("insert into test (ID,currentValue) values (" + i +"," +i + ")",sqlConn1);//不存在test表,此处会出现异常
sqlConn1.Open();
sqlCommand1.ExecuteNonQuery();
sqlConn1.Close();
i++;
}
}
}
说明:
post()方法将正常执行,post1()将抛出异常。通过结果可以看出post和post1操作的原子性
2. 利用强名工具sn.exe生成key,“sn -k key.snk”,将生成的key.snk拷贝到工程目录下,
[assembly: AssemblyKeyFileAttribute("..\..\BankComponent.snk")] 这句话将为程序集提供数字签名
3.编译生成.dll文件
4.注册COM+组件,我采用手工注册方式,据说比较保险,这相当于在该台机器上部署COM+服务
regsvcs BankComponentServ.dll
注册完成之后,在"控制面板->管理工具->组件服务"中,将可以看到以BankComponent命名的COM+服务
5.利用vs.net建立一个windows 应用程序,引用该dll,并调用其中的post,post1来测试事务
6.将另外一台PC的SQL Server 2000运行MTC服务
7.通过在"控制面板->管理工具->组件服务"的事务统计中,可以提交的事务和中止的事务。执行post的调用将被提交,
而post1的,全部被中止。