要实现COM+事务处理的类必须继承System.EnterpriseServices.ServicedComponent,这些类需要是公共的,并且需要提供一个公共的默认的构造器。
要找需要使用COM+事务处理的类定义以前加属性[Transaction(TransactionOption.Required)],这样类中的每一个方法都会运行在一个事务中。
项 |
说明 |
禁用 |
指示 XML Web services 方法不在事务的范围内运行。当处理请求时,将在没有事务的情况下执行 XML Web services 方法。 [WebMethod(TransactionOption= TransactionOption.Disabled)] |
NotSupported |
指示 XML Web services 方法不在事务的范围内运行。当处理请求时,将在没有事务的情况下执行 XML Web services 方法。 [WebMethod(TransactionOption= TransactionOption.NotSupported)] |
Supported |
指示 XML Web services 方法不在事务范围内运行。当处理请求时,将在没有事务的情况下创建 XML Web services。 [WebMethod(TransactionOption= TransactionOption.Supported)] |
必选 |
指示 XML Web services 方法需要事务。由于 XML Web services 方法只能作为根对象参与事务,因此将为 XML Web services 方法创建一个新事务。 [WebMethod(TransactionOption= TransactionOption.Required)] |
RequiresNew |
指示 XML Web services 方法需要新事务。当处理请求时,将在新事务内创建 XML Web services。 [WebMethod(TransactionOption= TransactionOption.RequiresNew)] |
COM+事务处理有手动处理和自动处理两种方式。
(1)自动处理就是在所需要自动处理的方法钱加上[AutoComplete],根据方法的正常或抛出异常决定提交或回滚。
(2)手动处理就是调用ContextUtil对象中的EnableCommit、SetComplete和SetAbout方法。
实现步骤:
1、给程序添加强名
1)创建一对密钥
使用sn.exe执行 sn -k C:\Key.snk
其中key.snk代表将保存密钥的文件名称。
2)签名
这个文件必须在AssemblyKeyFile属性中引用,签名通常是在编译时进行的。打开工程中的AssemblyInfo.cs文件进行修改
[assembly:AssemblyKeyFile("路径\Key.snk")]
key.snk文件和项目文件必须在同一个文件夹中。
2、手动事务处理
using System.EnterpriseServices;
[Transaction(TransactionOption.Required)]
public
class
OrderData1 : ServicedComponent
{
//
手动事务
public
string
WorkTran()
{
try
{
ContextUtil.EnableCommit();
Work1();
Work2();
ContextUtil.SetComplete();
return
"
成功!
"
;
}
catch
(Exception ex)
{
ContextUtil.SetAbort();
return
"
失败!
"
;
}
}
private
void
Work1()
{
string
conString
=
"
data source=127.0.0.1;database=codematic;user id=sa;password=
"
;
SqlConnection myConnection
=
new
SqlConnection(conString);
string
strSql
=
"
Insert Into P_Category(CategoryId,Name)values('1','test1')
"
;
SqlCommand myCommand
=
new
SqlCommand(strSql, myConnection);
myConnection.Open();
int
rows
=
myCommand.ExecuteNonQuery();
myConnection.Close();
}
private
void
Work2()
{
string
conString
=
"
data source=127.0.0.1;database=codematic;user id=sa;password=
"
;
SqlConnection myConnection
=
new
SqlConnection(conString);
string
strSql
=
"
Insert Into P_Category(CategoryId,Name)values('2','test2')
"
;
SqlCommand myCommand
=
new
SqlCommand(strSql, myConnection);
myConnection.Open();
int
rows
=
myCommand.ExecuteNonQuery();
myConnection.Close();
}
}
3、自动事务处理
using System.EnterpriseServices;//企业级服务COM+事务
namespace
ClassTran
{
///
<summary>
///
自动事务
///
</summary>
[Transaction(TransactionOption.Required)]
public
class
OrderData2 : ServicedComponent
{
//
自动事务
[AutoComplete(
true
)]
public
string
WorkTran()
{
string
msg
=
""
;
string
conString
=
"
data source=127.0.0.1;database=codematic;user id=sa;password=
"
;
SqlConnection myConnection
=
new
SqlConnection(conString);
myConnection.Open();
SqlCommand myCommand
=
new
SqlCommand();
myCommand.Connection
=
myConnection;
try
{
myCommand.CommandText
=
"
update P_Product set Name='电脑2' where Id=52
"
;
myCommand.ExecuteNonQuery();
myCommand.CommandText
=
"
update P_Product set Name='电脑3' where Id=53
"
;
myCommand.ExecuteNonQuery();
msg
=
"
成功!
"
;
}
catch
(Exception ex)
{
msg
=
"
失败:
"
+
ex.Message;
}
finally
{
myConnection.Close();
}
return
msg;
}
}
}
在需要事务跨MSMQ和其他可识别事务的资源(如SQL Server数据库)运行的系统中,只能使用DTC或COM+事务。
使用COM+事务导致性能降低
使用Enterprise Services的事务总是线程安全的,无让多个线程参与到同一个事务中