KB-Transaction Error When Query Oracle Database Links
1 |
同事遇到一個狀況,使用OleDbCommand查詢ORACLE上的Database Link時,系統回報以下錯誤:
ORA-02041: client database did not begin a transaction
Goggle了一下,發現問問題的人挺多的,但回答很分歧,沒法一下子得到正解。反覆測試後,我得到的結論如後。
當使用Oracle Database Link時,因涉及兩台以上的Oracle Server,自動啟用Distributed Transaction可以被理解(SQL Server亦是如此)。但網路上的討論似乎都集中火力在避免啟用Distributed Transaction上,而不是研究怎麼順利啟用它。Anyway,我試出兩種成功的做法。第一種是用ORACLE提供的OLEDB,關鍵是要將Registry中的HKLM\SOFTWARE\ORACLE\OLEDB\DistribTX由1改為0,表示停用分散式交易(我懷疑這會導致所有的Oracle OLEDB操作都失去分散式交易的能力,值得留意)。程式碼如下:
1: static void testOraOle()
2: {
3: OleDbConnection cn =
4: new OleDbConnection(
5: "Provider=OraOLEDB.Oracle; Data Source=Ora1; " +
6: "User Id=blah; Password=blahblah;");
7: cn.Open();
8: OleDbCommand cmd =
9: new OleDbCommand("select * from myTable@Ora2", cn);
10: OleDbDataReader dr = cmd.ExecuteReader();
11: while (dr.Read())
12: Console.WriteLine(dr[0].ToString());
13: dr.Close();
14: cn.Close();
15: }
使用ODP.NET時,關鍵則在Connection String中要加上Enlist=false停用分散式交易,如下:
1: static void testOraODP()
2: {
3: //程式碼要宣告using ODP = Oracle.DataAccess.Client;
4: ODP.OracleConnection cn =
5: new ODP.OracleConnection(
6: "Data Source=Ora1; User Id=blah; Password=blahblah; " +
7: "Enlist=false;");
8: cn.Open();
9: ODP.OracleCommand cmd =
10: new ODP.OracleCommand("select * from myTable@Ora2", cn);
11: ODP.OracleDataReader dr = cmd.ExecuteReader();
12: while (dr.Read())
13: Console.WriteLine(dr[0].ToString());
14: dr.Close();
15: cn.Close();
16: }
至於System.Data.OracleClient,在我的測試中,即使加上Enlist=false仍會傳回相同錯誤,是否註定無法支援或仍有其他的解法,暫時不得而知,若有人有成功案例再反應給我吧!
Comments
# by 路人甲
ADO 連線字串加上 DistribTX=0 或 ODBC 就要設置 MTS=T