.NET开发常用的事务机制有以下几种:
【1】SQL和存储过程级别的事务;
【2】ADO.NET级别的事务;
【3】ASP.NET页面级别的事务;
【4】企业级服务COM+事务;【本博客将介绍】
【5】System.Transactions事务处理。
【PS】部分转载《项目中的.NET一书》
.NET 依靠MTS/COM+服务来支持自动事务处理。要实现COM+事务处理的类,必须继承System.EnterpriseServices.ServicedComponent。
这些类需要是公共的,并且需要提供一共的默认构造器。
Web.Server支持COM+事务,其继承了ServicedComponent。
因此要在类定义之前加属性[Transaction(TransactionOption.Required)]。这样,类中的每一个方法都会运行在一个事务中。
那么我们具体应该怎样实现该事务呢??
【1】定义一个COM+事务处理的类时,首先引用:using System.EnterpriseServices; //企业级服务COM+事务
【2】继承ServicedComponent。方法如下:
[Transaction(TransactionOption.Required)]
public class OrderData1 : ServicedComponent
{
//事务处理方法,此处略!!!(*^__^*)
}
☆☆TransactionOption枚举类型有五个值:
public enum TransactionOption
{
Disabled, //(忽略当前上下文中的任何事务)
NotSupported,//(使用非受控事务在上下文中创建组件)
Supported, //(如果事务存在,则共享该事务)
Required, //(如果事务存在,则共享事务,并且如果有必要,可创建新事务)
RequiresNew //(使用新事务创建组件,而与当前上下文的状态无关)
}
【3】COM+事务有【手动处理】和【自动处理】两种方式:
(1)自动处理:就是在所需要自动处理的方法前加上 [AutoComplete(true)],根据方法的正常或抛出异常决定提交或回滚操作;
(2)手动处理:就是显式调用ContextUtil类中的EnableCommit、SetComplete和SetAbort方法。
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
华丽丽而无奈的分割线【实例演示出结论】
代码源自李天平老师《项目中的.NET》一书
**************************************************************************************************************************
为了说明这个问题,咱们来个实例说明:
(1)在页面添加两个按钮【手动事务】【自动事务】
在后台实现事务方法的调用:
/// <summary>
/// 手动事务
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Button1_Click(object sender, EventArgs e)
{
ClassTran.OrderData1 od1 = new ClassTran.OrderData1();
string strmsg = od1.WorkTran();
}
/// <summary>
/// 自动事务
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Button2_Click(object sender, EventArgs e)
{
ClassTran.OrderData2 od2 = new ClassTran.OrderData2();
string strmsg = od2.WorkTran();
}
这里在项目中创建一个实现事务处理的业务类ClassTran
(2)手动事务处理:【代码实例】
using System.EnterpriseServices;//企业级服务COM+事务
namespace ClassTran
{
/// <summary>
/// /手动事务
/// </summary>
[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)自动事务处理:【代码实例】
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;
}
}
}