做企業級服務com+事務幾個注意點

做企業級服務com+事務幾個注意點

1.給程序添加強名

1.1創建密鑰

用sn.exe共享工具 sn -k c:/key.snk  (注:key可以任意,snk後綴最好保留)

1.2簽名

在AssemblyInfo.cs文件中修改

[assembly:AssemblyKeyFile(@"G:/VS2008/ASPNETCodes/事務處理/事務處理/bin/key.snk")]

 [assembly: ComVisible(false)]改爲 [assembly: ComVisible(true)],

不然會出現在程序集中找到無效的 ServicedComponent 派生類。

2.事務處理

2.1手動處理

引入using System.EnterpriseServices

 

編寫代碼,例子:

 

 [Transaction(TransactionOption.Required)]

    public class Order1 : ServicedComponent
    {
        private static string constr = ConfigurationManager.ConnectionStrings["strsql"].ToString();

     
        //手動事務
        public string WorkTran()
        {
            try
            {
                ContextUtil.EnableCommit();
                Work1();
                Work2();
                ContextUtil.SetComplete();
                return "成功";
            }
            catch (Exception ex)
            {
                ContextUtil.SetAbort();
                return "失敗" + ex.ToString();
            }
        }


        private void Work1()
        {
            SqlConnection conn = new SqlConnection(constr);
            string sqlstr = "insert into P_Category(CategoryId,Name)values('10','test10')";
            SqlCommand cmd = new SqlCommand(sqlstr, conn);
            conn.Open();
            int rows = cmd.ExecuteNonQuery();
            conn.Close();

        }
        private void Work2()
        {
            SqlConnection conn = new SqlConnection(constr);
            string sqlstr = "insert into P_Category(CategoryId,Name)values('12','test12')";
            SqlCommand cmd = new SqlCommand(sqlstr, conn);
            conn.Open();
            int rows = cmd.ExecuteNonQuery();
            conn.Close();

        }
    }

 

調用

        protected void Button1_Click(object sender, EventArgs e)
        {
            Order1 o1 = new Order1();
            Response.Write(o1.WorkTran());
        }

2.2自動事務處理

 

方法前加入[AutoComplete(true)]屬性,少了  ContextUtil.EnableCommit()等。

 

 

 

 

 

.NET技術是微軟大力推廣的下一代平臺技術,自從.NET技術架構Beta2版本的正式發佈,此項技術也逐漸走向成熟和穩定。按照微軟的平臺系統佔有率,我們不難想象得到,在未來的一兩年內.NET技術必定會勢如破竹一般的登上主流的技術平臺,而一個新的技術平臺得以快速發展的最重要的前提是:他不會徹底的摒棄以前的技術,這一點對於.NET技術來說指的就是COM/COM+技術了。
 

一般來說,在IT技術界以及硬件產業,技術的更新換代速度非常得驚人,而慣例是所有的新技術都會遵循向下兼容的原則,但是.NET技術不僅僅做到了這一點,.NET甚至實現了相互之間的各自調用,這一點是非常難能可貴的。也就是說,不但我們可以在.NET組件中調用COM組件,同時也可以在COM組件中正常的調用.NET組件。這點帶來的好處是顯而易見的,一方面我們可以保持現有的技術資源,另一方面,在現有資源中可以利用.NET所帶來的各種新技術。

一般的數據庫事務控制要求事務裏所做的操作必須在同一個數據庫內,這樣在出現錯誤的時候才能回滾(RllBack)到初始狀態。這就存在一個問題,在分佈式應用程序中,我們往往需要同時操作多個數據庫,使用數據庫本身的事務處理,很難滿足程序對事務控制的要求。在COM+中,提供了完整的事務服務,我們可以利用它來完成在分佈式應用程序中的事務控制。

具體過程如下
一:用VS.NET生成一個類庫 。
二:添加對System.EnterpristServices的引用,具體步驟菜單:(項目-添加引用-在.NET選項卡選擇System.EnterpristServices-確定)
三:構建類
1:源程序
using System;
using System.EnterpriseServices;
using System.Data.SqlClient;
using System.Reflection;
namespace COMPlusSamples
{
//表明需要事務支持
[ Transaction(TransactionOption.Required) ]
//聲明爲服務器應用程序,還可以選擇Library,表示爲庫應用程序
[assembly: ApplicationActivation(ActivationOption.Server)]
//描述信息
[assembly: Description("sample")]

public class TxCfgClass : ServicedComponent
{
private static string init1 = "user id=sa;password=;initial catalog=pubs;data source=(local)";
private static string init2 = "user id=sa;password=;initial catalog=NorthWind;data source=(local)";
private static string add1 = "insert into authors('au_lname','au_fname') values('test1', 'test2')";
private static string add2 = "insert into sample values('test1',22)";
//the error sql statement
//there is not table “sample”
public TxCfgClass() {}
private void ExecSQL(string init, string sql)
{
SqlConnection conn = new SqlConnection(init);
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = sql;
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}

//添加一條記錄到數據庫
public void Add()
{
try
{
//在一數據庫中插入一條記錄
ExecSQL(init1, add1);
Console.WriteLine("the operation in the same database completely");
//在另外一個數據庫中插入兩條記錄
//這次執行的是一個錯誤的SQL語句
ExecSQL(init2, add2);
Console.WriteLine("the operation in the other database completely");
Console.WriteLine("Record(s) added, press enter...");
Console.Read();
}

catch(Exception e)
{
//事務回滾
ContextUtil.SetAbort();
Console.WriteLine("Because there are some errors in the operation ,so transcation abort");
Console.WriteLine("The error is " + e.Message);
Console.WriteLine("abort successfully");
Console.Read();
}
}
}
}

2:程序說明:

添加命名空間 using System.EnterpriseServices;因爲本程序使用了其中的ContextUtil類 [ Transaction(TransactionOption.Required) ] 說明DLL需要事務支持本程序的TxCfgClass 類從ServicedComponent類中繼承,這樣並不會影響該類,而只是在該類中添加了兩個額外的方法,這兩個方法可以使代碼共享變得更加容易.程序使用的sql server數據庫在本機運行,init1 和 init2是兩個連接數據庫的連接字符串,init連接pubs數據庫,inin2連接northwind數據庫,這是sql2000中自帶的示例數據庫。add1和add2是兩條sql語句,作用是分別向兩個數據庫的表裏添加一條記錄。注意:add2是一條錯誤的語句,因爲根本沒有sample表,這樣,會在執行時引起異常。(這正是我們所期望的)

在執行到add2語句時,由於它是錯誤的,所以會引發異常,轉到錯誤處理語句裏來執行。
ContextUtil.SetAbort();該語句使所有的數據庫操作回滾,這樣add1語句所插入的記錄也將不存在。(達到預期目標)

四:給程序添加強名(strong name)
1:創建一對密鑰
用來創建密鑰的工具是稱爲sn.exe的共享工具。通常通過命令提示運行它,該工具可執行各種任務以生成並提取密鑰。我們需要用以下方式來運行sn.exe。
sn –k key.snk
其中key.snk 代表將保存密鑰的文件的名稱。它的名稱可以是任意的,不過習慣上帶有.snk後綴名。

2:簽名
簽名通常是在編譯時進行的。簽名時,用戶可利用C#屬性通知編譯器應該使用正確的密鑰文件對DLL進行簽名。要做到這一點用戶需要打開工程中的AssemblyInfo.cs文件並進行修改。
[assembly:AssemblyKeyFile(“..//..//key.snk”)]
注:key.snk文件和項目文件在同一個文件夾

五:編譯成DLL (具體步驟)
菜單:(生成-生成)
如果一切正常,就會生成DLL文件

六:使用regsvcs.exe將Dll註冊到COM+ Services裏面
我們需要用以下方式運行regsvcs.exe
regsvcs dll文件名
如果一切正常的話,regsvcs.exe就會把dll輸入到COM+ Services中。

至此,我們已經生成並註冊了這個可以由其它程序使用的類,現在,我們來寫一個控制檯程序來檢驗這個類是否正常運行

七:構建客戶機
1:新建控制檯應用程序項目
菜單(文件-新建-項目) 選擇控制檯應用程序 ,並選擇 添入解決方案 ,確定

2:同上面的第二步一樣,添加對System.EnterpriseServices的引用。

3:添加對自己剛纔做好的類的引用。
菜單(項目-添加引用-瀏覽),選擇剛纔生成的DLL,確定

4:輸入以下程序

using System;
using COMPlusSamples;
using System.EnterpriseServices;
public class Client
{
public static void Main()
{
TxCfgClass cfg = new TxCfgClass();
cfg.Add();
}
}
.NET技術是微軟大力推廣的下一代平臺技術,自從.NET技術架構Beta2版本的正式發佈,此項技術也逐漸走向成熟和穩定。按照微軟的平臺系統佔有率,我們不難想象得到,在未來的一兩年內.NET技術必定會勢如破竹一般的登上主流的技術平臺,而一個新的技術平臺得以快速發展的最重要的前提是:他不會徹底的摒棄以前的技術,這一點對於.NET技術來說指的就是COM/COM+技術了。
 

一般來說,在IT技術界以及硬件產業,技術的更新換代速度非常得驚人,而慣例是所有的新技術都會遵循向下兼容的原則,但是.NET技術不僅僅做到了這一點,.NET甚至實現了相互之間的各自調用,這一點是非常難能可貴的。也就是說,不但我們可以在.NET組件中調用COM組件,同時也可以在COM組件中正常的調用.NET組件。這點帶來的好處是顯而易見的,一方面我們可以保持現有的技術資源,另一方面,在現有資源中可以利用.NET所帶來的各種新技術。

一般的數據庫事務控制要求事務裏所做的操作必須在同一個數據庫內,這樣在出現錯誤的時候才能回滾(RllBack)到初始狀態。這就存在一個問題,在分佈式應用程序中,我們往往需要同時操作多個數據庫,使用數據庫本身的事務處理,很難滿足程序對事務控制的要求。在COM+中,提供了完整的事務服務,我們可以利用它來完成在分佈式應用程序中的事務控制。

具體過程如下
一:用VS.NET生成一個類庫 。
二:添加對System.EnterpristServices的引用,具體步驟菜單:(項目-添加引用-在.NET選項卡選擇System.EnterpristServices-確定)
三:構建類
1:源程序
using System;
using System.EnterpriseServices;
using System.Data.SqlClient;
using System.Reflection;
namespace COMPlusSamples
{
//表明需要事務支持
[ Transaction(TransactionOption.Required) ]
//聲明爲服務器應用程序,還可以選擇Library,表示爲庫應用程序
[assembly: ApplicationActivation(ActivationOption.Server)]
//描述信息
[assembly: Description("sample")]

public class TxCfgClass : ServicedComponent
{
private static string init1 = "user id=sa;password=;initial catalog=pubs;data source=(local)";
private static string init2 = "user id=sa;password=;initial catalog=NorthWind;data source=(local)";
private static string add1 = "insert into authors('au_lname','au_fname') values('test1', 'test2')";
private static string add2 = "insert into sample values('test1',22)";
//the error sql statement
//there is not table “sample”
public TxCfgClass() {}
private void ExecSQL(string init, string sql)
{
SqlConnection conn = new SqlConnection(init);
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = sql;
conn.Open();
cmd.ExecuteNonQuery();
conn.Close();
}

//添加一條記錄到數據庫
public void Add()
{
try
{
//在一數據庫中插入一條記錄
ExecSQL(init1, add1);
Console.WriteLine("the operation in the same database completely");
//在另外一個數據庫中插入兩條記錄
//這次執行的是一個錯誤的SQL語句
ExecSQL(init2, add2);
Console.WriteLine("the operation in the other database completely");
Console.WriteLine("Record(s) added, press enter...");
Console.Read();
}

catch(Exception e)
{
//事務回滾
ContextUtil.SetAbort();
Console.WriteLine("Because there are some errors in the operation ,so transcation abort");
Console.WriteLine("The error is " + e.Message);
Console.WriteLine("abort successfully");
Console.Read();
}
}
}
}

2:程序說明:

添加命名空間 using System.EnterpriseServices;因爲本程序使用了其中的ContextUtil類 [ Transaction(TransactionOption.Required) ] 說明DLL需要事務支持本程序的TxCfgClass 類從ServicedComponent類中繼承,這樣並不會影響該類,而只是在該類中添加了兩個額外的方法,這兩個方法可以使代碼共享變得更加容易.程序使用的sql server數據庫在本機運行,init1 和 init2是兩個連接數據庫的連接字符串,init連接pubs數據庫,inin2連接northwind數據庫,這是sql2000中自帶的示例數據庫。add1和add2是兩條sql語句,作用是分別向兩個數據庫的表裏添加一條記錄。注意:add2是一條錯誤的語句,因爲根本沒有sample表,這樣,會在執行時引起異常。(這正是我們所期望的)

在執行到add2語句時,由於它是錯誤的,所以會引發異常,轉到錯誤處理語句裏來執行。
ContextUtil.SetAbort();該語句使所有的數據庫操作回滾,這樣add1語句所插入的記錄也將不存在。(達到預期目標)

四:給程序添加強名(strong name)
1:創建一對密鑰
用來創建密鑰的工具是稱爲sn.exe的共享工具。通常通過命令提示運行它,該工具可執行各種任務以生成並提取密鑰。我們需要用以下方式來運行sn.exe。
sn –k key.snk
其中key.snk 代表將保存密鑰的文件的名稱。它的名稱可以是任意的,不過習慣上帶有.snk後綴名。

2:簽名
簽名通常是在編譯時進行的。簽名時,用戶可利用C#屬性通知編譯器應該使用正確的密鑰文件對DLL進行簽名。要做到這一點用戶需要打開工程中的AssemblyInfo.cs文件並進行修改。
[assembly:AssemblyKeyFile(“..//..//key.snk”)]
注:key.snk文件和項目文件在同一個文件夾

五:編譯成DLL (具體步驟)
菜單:(生成-生成)
如果一切正常,就會生成DLL文件

六:使用regsvcs.exe將Dll註冊到COM+ Services裏面
我們需要用以下方式運行regsvcs.exe
regsvcs dll文件名
如果一切正常的話,regsvcs.exe就會把dll輸入到COM+ Services中。

至此,我們已經生成並註冊了這個可以由其它程序使用的類,現在,我們來寫一個控制檯程序來檢驗這個類是否正常運行

七:構建客戶機
1:新建控制檯應用程序項目
菜單(文件-新建-項目) 選擇控制檯應用程序 ,並選擇 添入解決方案 ,確定

2:同上面的第二步一樣,添加對System.EnterpriseServices的引用。

3:添加對自己剛纔做好的類的引用。
菜單(項目-添加引用-瀏覽),選擇剛纔生成的DLL,確定

4:輸入以下程序

using System;
using COMPlusSamples;
using System.EnterpriseServices;
public class Client
{
public static void Main()
{
TxCfgClass cfg = new TxCfgClass();
cfg.Add();
}
}

5:將控制檯程序設置爲啓動項,然後編譯運行,就會看到結果。
正如我們希望的,第一條記錄沒有插入數據庫


5:將控制檯程序設置爲啓動項,然後編譯運行,就會看到結果。
正如我們希望的,第一條記錄沒有插入數據庫

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章