如何在 Visual C# 组件中使用 COM+ 事务
1个回答
展开全部
要访问 COM+ 事务服务,需创建一个类。为此,请按照下列步骤操作: 启动Visual Studio .NET 或 Visual Studio 2005。在“文件”菜单上,指向“新建”,然后单击“项目”。单击“项目类型”下的“Visual C# 项目”,然后单击“模板”下的“类库”。将该项目命名为 prjEnterprise。
注意:在 Visual Studio 2005 中,请单击“项目类型”下的“Visual C#”,然后单击“模板”下的“类库”。将该项目命名为 prjEnterprise。默认情况下将创建 Class1。在解决方案资源管理器中,右键单击“引用”,然后单击“添加引用”。 将出现“添加引用”对话框。在“.NET”选项卡的“组件名称”下,双击“System.EnterpriseServices”。确保“System.EnterpriseServices”显示在“选定的组件”下。单击“确定”。 将以下代码添加到 Class1.cs 文件中的其他任何语句之前:
using System.EnterpriseServices; using System.Data.SqlClient;向Class1.cs 文件中添加一个名为 clsES 的新类。要使用 COM+ 事务服务,您的类 (clsES) 必须按如下方式从 ServicedComponent 继承功能:
public class clsES : ServicedComponent按如下方式使用一个 Transaction 属性来指定该类的事务支持级别:
[Transaction(TransactionOption.Required)]public class clsES : ServicedComponent在clsES 类中创建一个方法,然后将其命名为 dbAccess,该方法接收四个整数作为输入参数。前两个参数提供一个产品 ID 和这种产品的订货数量;后两个参数提供一个产品 ID 和这种产品的库存数量。该方法对这些指定的产品 ID 执行一组数据库操作,这组数据库操作将被视为一个事务:
void dbAccess(int pID1,int onOrder, int pID2, int inStock)在dbAccess 方法中,创建一个用于罗斯文数据库的 SQL 连接对象,然后打开该连接。数据库操作是使用以下数据库进行的:
注意:不要忘记更改下面的连接字符串参数以反映您的 SQL Server 服务器的正确值。
SqlConnection Conn = new SqlConnection("user id=<username>;password=<strong password>;Initial Catalog=northwind;Data Source=2E124\\SQL;"); Conn.Open(); 设置一个 try 块以捕获在数据库处理过程中可能出现的任何异常。您必须捕获这些异常来终止事务。try 块包括两个数据库操作,每个操作更新指定的 Products 表记录中的一个不同字段。
try { 对Products 表执行第一个更新。按照前两个输入参数的指定,使用 onOrder 值更新具有指定 ID 的产品的 UnitsonOrder 字段。使用下面的 SQL 命令运行这个 SQL 更新:
SqlCommand sqlCommand = new SqlCommand("UPDATE myProducts SET UnitsonOrder = " + onOrder + " WHERE productID = " + pID1, Conn); sqlCommand.ExecuteNonQuery();对Products 表执行另一个更新。按照第三个和第四个输入参数的指定,使用 inStock 值更新具有指定 ID 的产品的 UnitsinStock 字段。使用下面的 SQL 命令运行这个 SQL 更新:
sqlCommand.CommandText = "UPDATE myProducts SET UnitsinStock = " + inStock + " WHERE productID = " + pID2; sqlCommand.ExecuteNonQuery(); 因为这些更新是 COM+ 事务的一部分,所以它们作为一个单元提交。如果没有引发错误,将使用 System.EnterpriseServices 命名空间中的 contextUtil 类的setComplete 方法提交该事务(在本例中是两个更新):
ContextUtil.SetComplete();与罗斯文数据库的连接关闭:
Conn.Close(); }您必须捕获运行 SQL 命令时发生的任何异常以便能够终止整个事务:
catch(Exception e){ 使用System.EnterpriseServices 命名空间中的 contextUtil 类的setAbort 方法终止整个事务。如果第一个更新成功但第二个更新失败,则两个更新都不会发布到 Products 表。捕获到的异常将抛给调用者,表明事务已失败:
ContextUtil.SetAbort(); throw e; }为使该组件正确运行,该组件必须有一个强名称。生成一个强名称,然后使用该强名称对程序集进行签名。为此,请按照下列步骤操作: 在Visual Studio .NET 命令提示符处,键入 sn.exe -k snEnterprise.snk 以创建一个密钥文件。有关使用强名称对程序集进行签名的更多信息,请参见 .NET Framework SDK 文档。将snEnterprise.snk 复制到您的项目文件夹中。 在AssemblyInfo.vc 中,将以下代码行添加到其他程序集属性语句之前或之后:
[assembly: AssemblyKeyFileAttribute("..\\..\\snEnterprise.snk")] 进行保存,然后生成您的项目。完整代码列表注意:不要忘记更改下面的连接字符串参数以反映您的 SQL Server 服务器的正确值。
using System; using System.Data; using System.Data.SqlTypes; using System.Data.Common; using System.EnterpriseServices; using System.Data.SqlClient; namespace prjEnterprise { [Transaction(TransactionOption.Required)]public class clsES:ServicedComponent { public SqlConnection Conn; public void dbAccess(int pID1, int onOrder, int pID2, int inStock) { try { SqlConnection Conn = new SqlConnection("user id=<username>;password=<strong password>;Initial Catalog=northwind;Data Source=2E124\\SQL;"); Conn.Open(); SqlCommand sqlCommand = new SqlCommand("UPDATE myProducts SET UnitsonOrder = " + onOrder + " WHERE productID = " + pID1, Conn); sqlCommand.ExecuteNonQuery(); sqlCommand.CommandText = "UPDATE myProducts SET UnitsinStock = " + inStock + " WHERE productID = " + pID2; sqlCommand.ExecuteNonQuery(); ContextUtil.SetComplete(); Conn.Close(); } catch(Exception e) { ContextUtil.SetAbort(); throw e; } finally { } } } }确认它可以使用要测试这个代码,需要创建一个使用 clsES 项目的控制台应用程序。一种情形是:事务成功,指定产品的 onorder 和instock 字段得到了更新。另一种情形是:对一个指定产品的 onOrder 字段的更新成功了,但对另一个指定产品的 inStock 字段的更新失败了(因为在 Products 表中不存在指定的产品编号)。这会导致事务失败,该事务将被忽略。 在Visual Studio .NET 或 Visual Studio 2005 中,指向“文件”菜单上的“新建”,然后单击“项目”。 单击“项目类型”下的“Visual C# 项目”,然后单击“模板”下的“控制台应用程序”。
注意:在 Visual Studio 2005 中,请单击“项目类型”下的“Visual C#”,然后单击“模板”下的“控制台应用程序”。在“名称”文本框中,键入 testES。确保已选中了“添入解决方案”选项。 单击“确定”将该项目添加到解决方案中。要使testES 测试clsES,您必须添加一个引用。在解决方案资源管理器中,右键单击 testES(您刚才添加的)下的“引用”,然后单击“添加引用”。将出现“添加引用”对话框。在“项目”选项卡上,双击“prjEnterprise”。 在“选定的组件”下显示一个引用。单击“确定”向项目中添加该引用。在项目中添加对 System.EnterpriseServices 库的引用。在解决方案资源管理器中,右键单击“引用”,然后单击“添加引用”。将出现“添加引用”对话框。在“.NET”选项卡的“组件名称”下,双击“System.EnterpriseServices”。确保“System.EnterpriseServices”显示在“选定的组件”下。单击“确定”。 右键单击控制台应用程序 (testES),然后单击“设为启动项目”。将以下源代码粘贴到 Class1 类的Main 函数中:
prjEnterprise.clsES myTest = new prjEnterprise.clsES(); try { myTest.dbAccess(1, 777, 2, 888); Console.WriteLine("TRANSACTION ONE -- SUCCESS"); myTest.dbAccess(1, 5, 2, -20); Console.WriteLine("TRANSACTION TWO -- SUCCESS"); } catch (Exception e) { Console.WriteLine("TRANSACTION FAILURE"); }按F5 以运行测试代码。
在代码的步骤 7 中,对 dbAccess 的第一个调用成功完成。产品 1 和产品 2 均在 Products 表中。产品 1 的 onOrder 字段更新为 777,产品 2 的 inStock 字段更新为 888。因为这个事务成功完成,所以您将在输出窗口中收到以下消息
事务1 - 成功对dbAccess 的第二个调用失败。因此,不会将 dbAccess 中的对 Products 表的任何更新语句发布到数据库。虽然产品 1 本来可以将它的 onOrder 字段更新为 5,但是产品 2 不能将它的 inStock 字段设为 -20。(因为 Products 表定义中定义的一个约束条件规定 inStock 不允许为负数)。
因此,对 dbAccess 的这个调用失败了,从而整个事务也随之失败。Products 表将保持调用 dbAccess 之前的状态。catch 语句处理来自 dbAccess 的事务失败通知,您将在输出窗口中收到以下错误消息:
TRANSACTION FAILURE使用SQL Server 企业管理器检查罗斯文的 Products 表的内容。查看产品 1,onOrder 字段的值为 777。查看产品 2,instock 字段的值为 888。因此,对 dbAccess 的第二个调用(此调用本会使这些字段具有不同的值)失败了。疑难解答确保使用 COM+ 服务的所有项目都有一个强名称。使用COM+ 服务的所有类都必须继承服务组件。服务组件位于 System.EnterpriseServices 命名空间中。进行调试时,事务在提交或终止前可能会超时。要避免出现超时,请在事务属性中使用一个超时属性。在下面的示例中,在完成任何事务时,关联的方法在超时前都有 1,200 秒的执行时间:
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询