在.net 2.0 中执行分布式事务:隐式事务篇(SQL Server 与 Oracle)
生活随笔
收集整理的這篇文章主要介紹了
在.net 2.0 中执行分布式事务:隐式事务篇(SQL Server 与 Oracle)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
項(xiàng)目涉及到多個數(shù)據(jù)庫的查詢更新操作,也就必然需要分布式事務(wù)的支持,查了MSDN知道 .net 2.0 中利用新增的 System.Transactions 命名空間可以簡單的實(shí)現(xiàn)分布式事務(wù):
System.Transactions?基礎(chǔ)結(jié)構(gòu)通過支持在?SQL?Server、ADO.NET、MSMQ?和?Microsoft?分布式事務(wù)協(xié)調(diào)器?(MSDTC)?中啟動的事務(wù),使事務(wù)編程在整個平臺上變得簡單和高效。它提供基于?Transaction?類的顯式編程模型,還提供使用?TransactionScope?類的隱式編程模型,在這種模型中事務(wù)是由基礎(chǔ)結(jié)構(gòu)自動管理的。強(qiáng)烈建議使用更為方便的隱式模型進(jìn)行開發(fā)。 具體參考:http://msdn2.microsoft.com/zh-cn/library/system.transactions(VS.80).aspx 以及相關(guān)的連接都提供了非常詳細(xì)的信息參考MSDN的Demo做了SQL Server 2000 的 使用事務(wù)范圍實(shí)現(xiàn)隱式事務(wù)測試,事務(wù)可以正常提交以及回滾:
private?void?Test1()
????{
????????//?使用事務(wù)范圍實(shí)現(xiàn)隱式事務(wù)
????????//?ms-help://MS.VSCC.v80/MS.MSDN.v80/MS.VisualStudio.v80.chs/dv_fxtransactions/html/1ddba95e-7587-48b2-8838-708c275e7199.htm
????????using?(TransactionScope?ts?=?new?TransactionScope())?{
????????????//Create?and?open?the?SQL?connection.??The?work?done?on?this?connection?will?be?a?part?of?the?transaction?created?by?the?TransactionScope
????????????SqlConnection?myConnection?=?new?SqlConnection("server=(local);Integrated?Security=SSPI;database=northwind");
????????????SqlCommand?myCommand?=?new?SqlCommand();
????????????myConnection.Open();
????????????myCommand.Connection?=?myConnection;
????????????if?(!chkGenError.Checked)?{
????????????????//Restore?database?to?near?it's?original?condition?so?sample?will?work?correctly.
????????????????myCommand.CommandText?=?"DELETE?FROM?Region?WHERE?(RegionID?=?100)?OR?(RegionID?=?101)";
????????????????myCommand.ExecuteNonQuery();
????????????}
????????????//Insert?the?first?record.
????????????myCommand.CommandText?=?"Insert?into?Region?(RegionID,?RegionDescription)?VALUES?(100,?'MidWestern')";
????????????myCommand.ExecuteNonQuery();
????????????//Insert?the?second?record.
????????????myCommand.CommandText?=?"Insert?into?Region?(RegionID,?RegionDescription)?VALUES?(101,?'MidEastern')";
????????????myCommand.ExecuteNonQuery();
????????????myConnection.Close();
????????????if?(chkCommit.Checked)?{
????????????????ts.Complete();
????????????}
????????????/**/////Call?complete?on?the?TransactionScope?or?not?based?on?input
????????????//ConsoleKeyInfo?c;
????????????//while?(true)?{
????????????//????Console.Write("Complete?the?transaction?scope??[Y|N]?");
????????????//????c?=?Console.ReadKey();
????????????//????Console.WriteLine();
????????????//????if?((c.KeyChar?==?'Y')?||?(c.KeyChar?==?'y'))?{
????????????//????????//?Commit?the?transaction
????????????//????????ts.Complete();
????????????//????????break;
????????????//????}
????????????//????else?if?((c.KeyChar?==?'N')?||?(c.KeyChar?==?'n'))?{
????????????//????????break;
????????????//????}
????????????//}
????????}
????}
????private?void?Test2()
????{
????????string?connectString1?=?"server=(local);Integrated?Security=SSPI;database=northwind";
????????string?connectString2?=?"server=(local);Integrated?Security=SSPI;database=pubs";
????????string?dt?=?DateTime.Now.ToString();
????????using?(TransactionScope?transScope?=?new?TransactionScope())?{
????????????using?(SqlConnection?connection1?=?new
???????????????SqlConnection(connectString1))?{
????????????????//?Opening?connection1?automatically?enlists?it?in?the?
????????????????//?TransactionScope?as?a?lightweight?transaction.
????????????????connection1.Open();
????????????????//?Do?work?in?the?first?connection.
????????????????SqlCommand?command1?=?new?SqlCommand();????????????????
????????????????command1.Connection?=?connection1;
????????????????//Restore?database?to?near?it's?original?condition?so?sample?will?work?correctly.
????????????????command1.CommandText?=?"DELETE?FROM?Region?WHERE?(RegionID?=?100)?OR?(RegionID?=?101)";
????????????????command1.ExecuteNonQuery();
????????????????//Insert?the?first?record.
????????????????command1.CommandText?=?"Insert?into?Region?(RegionID,?RegionDescription)?VALUES?(100,?'MidWestern')";
????????????????command1.ExecuteNonQuery();
????????????????//Insert?the?second?record.
????????????????command1.CommandText?=?"Insert?into?Region?(RegionID,?RegionDescription)?VALUES?(101,?'MidEastern')";
????????????????command1.ExecuteNonQuery();
????????????????//?Assumes?conditional?logic?in?place?where?the?second
????????????????//?connection?will?only?be?opened?as?needed.
????????????????using?(SqlConnection?connection2?=?new
????????????????????SqlConnection(connectString2))?{
????????????????????//?Open?the?second?connection,?which?enlists?the?
????????????????????//?second?connection?and?promotes?the?transaction?to
????????????????????//?a?full?distributed?transaction.?
????????????????????connection2.Open();
???????????????????
????????????????????//?Do?work?in?the?second?connection.
????????????????????SqlCommand?command2?=?new?SqlCommand();????????????????????
????????????????????command2.Connection?=?connection2;
????????????????????if?(!chkGenError.Checked)?{
????????????????????????//Restore?database?to?near?it's?original?condition?so?sample?will?work?correctly.
????????????????????????command2.CommandText?=?"DELETE?FROM?stores?WHERE?(stor_id?=?'9797')?OR?(stor_id?=?'9798')";
????????????????????????command2.ExecuteNonQuery();
????????????????????}
????????????????????//Insert?the?first?record.
????????????????????command2.CommandText?=?"Insert?into?stores?(stor_id,?stor_name)?VALUES?('9797',?'ebay')";
????????????????????command2.ExecuteNonQuery();
????????????????????//Insert?the?second?record.
????????????????????command2.CommandText?=?"Insert?into?stores?(stor_id,?stor_name)?VALUES?('9798',?'amazon')";
????????????????????command2.ExecuteNonQuery();????????????????????
????????????????}
????????????}
????????????//??The?Complete?method?commits?the?transaction.
????????????if?(chkCommit.Checked)?{
????????????????transScope.Complete();
????????????}
????????}
????}
????private?void?Test3()
????{
????????string?connectString1?=?"server=(local);Integrated?Security=SSPI;database=northwind";
????????string?connectString2?=?"server=(local);Integrated?Security=SSPI;database=pubs";
????????string?dt?=?DateTime.Now.ToString();
????????using?(TransactionScope?transScope?=?new?TransactionScope())?{
????????????using?(SqlConnection?connection1?=?new
???????????????SqlConnection(connectString1))?{
????????????????//?Opening?connection1?automatically?enlists?it?in?the?
????????????????//?TransactionScope?as?a?lightweight?transaction.
????????????????connection1.Open();
????????????????//?Do?work?in?the?first?connection.
????????????????SqlCommand?command1?=?new?SqlCommand();
????????????????command1.Connection?=?connection1;
????????????????//Restore?database?to?near?it's?original?condition?so?sample?will?work?correctly.
????????????????command1.CommandText?=?"DELETE?FROM?Region?WHERE?(RegionID?=?100)?OR?(RegionID?=?101)";
????????????????command1.ExecuteNonQuery();
????????????????//Insert?the?first?record.
????????????????command1.CommandText?=?"Insert?into?Region?(RegionID,?RegionDescription)?VALUES?(100,?'MidWestern')";
????????????????command1.ExecuteNonQuery();
????????????????//Insert?the?second?record.
????????????????command1.CommandText?=?"Insert?into?Region?(RegionID,?RegionDescription)?VALUES?(101,?'MidEastern')";
????????????????command1.ExecuteNonQuery();
????????????}
????????????//?Assumes?conditional?logic?in?place?where?the?second
????????????//?connection?will?only?be?opened?as?needed.
????????????using?(SqlConnection?connection2?=?new
????????????????SqlConnection(connectString2))?{
????????????????//?Open?the?second?connection,?which?enlists?the?
????????????????//?second?connection?and?promotes?the?transaction?to
????????????????//?a?full?distributed?transaction.?
????????????????connection2.Open();
????????????????//?Do?work?in?the?second?connection.
????????????????SqlCommand?command2?=?new?SqlCommand();
????????????????command2.Connection?=?connection2;
????????????????if?(!chkGenError.Checked)?{
????????????????????//Restore?database?to?near?it's?original?condition?so?sample?will?work?correctly.
????????????????????command2.CommandText?=?"DELETE?FROM?stores?WHERE?(stor_id?=?'9797')?OR?(stor_id?=?'9798')";
????????????????????command2.ExecuteNonQuery();
????????????????}
????????????????//Insert?the?first?record.
????????????????command2.CommandText?=?"Insert?into?stores?(stor_id,?stor_name)?VALUES?('9797',?'ebay')";
????????????????command2.ExecuteNonQuery();
????????????????//Insert?the?second?record.
????????????????command2.CommandText?=?"Insert?into?stores?(stor_id,?stor_name)?VALUES?('9798',?'amazon')";
????????????????command2.ExecuteNonQuery();
????????????}
????????????//??The?Complete?method?commits?the?transaction.
????????????if?(chkCommit.Checked)?{
????????????????transScope.Complete();
????????????}
????????}
????}????
?
測試的時候需要在 Sql Server 服務(wù)管理器中開啟 MSDTC,我是再 SQL 2k上做的測試,2k5上應(yīng)該得到更好的支持。
方法 Test1()?是單數(shù)據(jù)庫的事務(wù),只是為了測試;
?Test2()和Test3() 沒有實(shí)質(zhì)區(qū)別,都是自動注冊事務(wù)。
完整代碼下載:/Files/Jinglecat/DTCSQL.rar
同時我也嘗試了一個Oracle版本,Oracle 10g 2,其中數(shù)據(jù)庫orcl 是默認(rèn)的啟動數(shù)據(jù)庫,而數(shù)據(jù)庫nhrs是我自己建的一個數(shù)據(jù)庫,測試通過,代碼跟SQL沒有兩樣,之前網(wǎng)上查到有網(wǎng)友說OracleClient還不支持 MSDTC,查了很多資料,確實(shí)在 ado.net 1.x 有問題,現(xiàn)在可以確信 ado.net 2.0 已經(jīng)可以支持。
完整代碼下載:/Files/Jinglecat/DTCORA.rar
現(xiàn)在銀杏事務(wù)已經(jīng)可以滿數(shù)項(xiàng)目需求了,有時間再多更多的研究了^_^
轉(zhuǎn)載于:https://www.cnblogs.com/Jinglecat/archive/2007/04/07/704297.html
總結(jié)
以上是生活随笔為你收集整理的在.net 2.0 中执行分布式事务:隐式事务篇(SQL Server 与 Oracle)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【数据结构与算法】【算法思想】【MySQ
- 下一篇: mssql数据库置疑修复