using System;
using System.EnterpriseServices;
using System.Data;
using System.Data.OleDb;
using System.Data.SqlClient;
using System.Runtime.InteropServices;namespace MyControls.ComServices.Transaction
{
         public interface ITxTest
{
bool UpDate(int nID1 , string sName1 , int nID2 , string sName2);
} [Guid("FC051C1E-8568-45a5-A7AD-59C6727846B9")]
[Transaction(TransactionOption.Required )]
[Synchronization(SynchronizationOption.Required)]
[JustInTimeActivation(true)] public class TxTest:ServicedComponent,ITxTest
{
             .
             .
             .
             .
}
}你去试试看,当然,你要先形成强名称,和*.snk文件

解决方案 »

  1.   

    兄弟,還是不行啊!!
    有哪位仁兄做過帶Transaction的COM+ , 能不能把sample給我看看,謝謝
    [email protected]
      

  2.   

    或者在客户端使用ITransactionContext激活你要使用的对象。注意:你必须在方法返回后钝化你的对象才行。(不推荐用RequireNew)
      

  3.   

    再给你看看我最近才参悟透的Com+
    using System;
    using System.Data;
    using System.Collections;
    using System.Data.SqlClient;
    using System.EnterpriseServices;
    using System.Runtime.InteropServices;namespace HexudongSoftWareDll
    {
    public interface IHexudongSoftWare
    {
    long InsertUser(User obj);
    void UpdateUser(User obj);
    void DeleteUser(long ID);
    }    [Guid("FC051C1E-8568-45a5-A7AD-59C6727846B9")]
    [Transaction(TransactionOption.Required )]
    [Synchronization(SynchronizationOption.Required)]
    [JustInTimeActivation(true)] /// <summary>
    /// MyProcessDAL 的摘要说明。
    /// </summary>
    public class MyProcessDAL:ServicedComponent,IHexudongSoftWare
    {
    //建立指向数据库的连接
    // string strCon = "server=localhost;uid=sa;pwd=;database=MyData" ;
    string strCon=System.Configuration.ConfigurationSettings.AppSettings["HeXuDongSoftWare.ConnectionString"]; public MyProcessDAL()
    {
    //
    // TODO: 在此处添加构造函数逻辑
    //
    } #region 用户操作

    public long InsertUser(User obj)
    {
    long indentity=0;
    try
    {
    SqlConnection aConnection = new SqlConnection(strCon);
    // 打开指向数据库连接
    aConnection.Open ( ) ;
    SqlCommand cmdInsert=new SqlCommand();
    cmdInsert.Connection=aConnection;
                    //设置 INSERT 命令
    string strSQL="INSERT INTO Users"+
    "(Code,Name,State,Password)"+
    "Values(@Code,@Name,@State,@Password)";                
    cmdInsert.CommandText=strSQL;
                    //设置相应的INSERT 命令中的参数值
    cmdInsert.Parameters.Add(new SqlParameter("@Code",obj.Code));
    cmdInsert.Parameters.Add(new SqlParameter("@Name",obj.Name));
    cmdInsert.Parameters.Add(new SqlParameter("@State",obj.State));
    cmdInsert.Parameters.Add(new SqlParameter("@Password",obj.Password));
                    //把纪录插入表中
    cmdInsert.ExecuteNonQuery();
                    //取得ID值
    cmdInsert.CommandText="SELECT @@IDENTITY as ID "; 
    SqlDataReader sqlReader=cmdInsert.ExecuteReader();
    sqlReader.Read();
                    indentity=Convert.ToInt64(sqlReader["ID"]);
    sqlReader.Close();
                    //关闭数据库的连接
    aConnection.Close();
     
    //通知COM+已成功完成插入操作,可以提交事务并释放对象.
    //当为AutoComplete属性的必须这样申明
    ContextUtil.SetComplete();
    }
    catch(Exception excep)
    {
    //通知COM+插入操作不成功,退出事务并释放对象.
    //当为AutoComplete属性的必须这样申明
    ContextUtil.SetAbort();
    throw excep;
    }
    return indentity;
    } public void UpdateUser(User obj)
    {
    try
    {
    SqlConnection aConnection = new SqlConnection(strCon);
    // 打开指向数据库连接
    aConnection.Open ( ) ;
    SqlCommand cmdUpdate=new SqlCommand();
    cmdUpdate.Connection=aConnection;
    //设置 UPDATE 命令
    string strSQL="UPDATE Users SET "+
    "Code=@Code,Name=@Name,State=@State,Password=@Password  "+
    "WHERE ID=@ID ";            
    cmdUpdate.CommandText=strSQL;
    //设置相应的UPDATE命令中的参数值
    cmdUpdate.Parameters.Add(new SqlParameter("@ID",obj.ID));
    cmdUpdate.Parameters.Add(new SqlParameter("@Code",obj.Code));
    cmdUpdate.Parameters.Add(new SqlParameter("@Name",obj.Name));
    cmdUpdate.Parameters.Add(new SqlParameter("@State",obj.State));
    cmdUpdate.Parameters.Add(new SqlParameter("@Password",obj.Password));
    //执行UPDATE
    cmdUpdate.ExecuteNonQuery();
    //关闭数据库的连接
    aConnection.Close();
    //通知COM+已成功完成插入操作,可以提交事务并释放对象.
    //当为AutoComplete属性的必须这样申明
    ContextUtil.SetComplete();
    }
    catch(Exception excep)
    {
    //通知COM+插入操作不成功,退出事务并释放对象.
    //当为AutoComplete属性的必须这样申明
    ContextUtil.SetAbort();
    throw excep;
    }
    } public void DeleteUser(long ID)
    {
    try
    {
    SqlConnection aConnection = new SqlConnection(strCon);
    // 打开指向数据库连接
    aConnection.Open ( ) ;
    SqlCommand cmdDelete=new SqlCommand();
    cmdDelete.Connection=aConnection;
    //设置 DELETE 命令
    string strSQL="DELETE FROM Users  WHERE ID=@ID ";  
    cmdDelete.CommandText=strSQL;
    //设置相应的DELETE命令中的参数值
    cmdDelete.Parameters.Add(new SqlParameter("@ID",ID));
    //执行DELETE
    cmdDelete.ExecuteNonQuery();
    //关闭数据库的连接
    aConnection.Close();
    //通知COM+已成功完成插入操作,可以提交事务并释放对象.
    //当为AutoComplete属性的必须这样申明
    ContextUtil.SetComplete();
    }
    catch(Exception excep)
    {
    //通知COM+插入操作不成功,退出事务并释放对象.
    //当为AutoComplete属性的必须这样申明
    ContextUtil.SetAbort();
    throw excep;
    }
    }
    #endregion
    }
    }
      

  4.   

    To : Hexudong1979(何须懂何必懂) 
    你的Transaction能用嗎??
    有沒有試用OLEDBConnection創建連接??
      

  5.   

    多谢谢lihao9806(李昊)的指导,我都测试过的啊,都对的了
    请问我错在哪里啊,我最近是在学这方面的东西
    也欢迎大家来指教,指正我的错误
    非常感激
      

  6.   

    那就怪了
    為什麼我的Transcation就不行的呢
    報了這個看不懂的錯誤 "沒有錯誤資訊: XACT_E_NOENLIST(0x8004D00A)"。
      

  7.   

    問題找到了;
    對於Oracle的OLEDB連接 ,COM+ 存在問題(應該是Bug)
    例如;
    Provider=msdaora;
    Provider=OraOLEDB.Oracle
    都存在該問題
    而將Oracle Server換成 Sql Server
    同樣是OleDb連接,問題解決.
    Provider=sqloledb由此可以推斷這是.Net對Oracle的支持的不足.
    環境;
      win2000 Professional + VS.Net 2002 + Oracle 8i
      

  8.   

    TO:Hexudong1979(何须懂何必懂)
    1、代码不简洁
    [Transaction(TransactionOption.Required )]
    [Synchronization(SynchronizationOption.Required)]
    [JustInTimeActivation(true)]
    写为:
    [Transaction]
    [Synchronization]
    [JustInTimeActivation]
    就可以了,反正你用的是默认值。
    2、使用事务支持就默认JITA了,所以不用声明[JustInTimeActivation]
    3、你也没有显式地钝化对象,所以在使用对象池的时候,可能会出问题。(因为.net的垃圾回收不定在什么时候运行,导致对象永远不能放回池中。)而且,只有在钝化后对象对事务的投票才生效。(你可以看看ms的例子,它都会显式钝化对象)
    4、尽量不要使用try...catch...的方式进行事务处理(虽然这最常见)。异常处理可能会影响效率。而且,最好让异常沿调用链向上传播。我也是刚学,以上几点也都是吹毛求疵,见笑了。(说错的地方请指教)