• 締切済み

.NET Framework(C#)で分散トランザクションを行う方法

SQL Server 2000と.NET Framework(C#)で、手動の分散トランザクションを行いたいのですが、MSDN調べても断片的なものしか得られず、わかりません。 あちこち探しても概念的な話はあっても、実際にサンプルとなるようなコードレベルの物は見つけられずに悩んでいます。 どこかにサンプルとなるような具体的なコード、又は解説などがあるURLや、MSDNのここを見ればわかるのような情報ありましたらお願いします。 もちろん、具体的に説明してもらえるならそれでもいいです。ここで説明できる程度におさまらないような気もしますが。

みんなの回答

  • 7marine
  • ベストアンサー率36% (59/160)
回答No.1

確かにMSDNで調べても分かりやすいサンプルないですね。 実装をしたことはないので、自信無いですけどスケルトンを作ってみました。参考になれば幸いです。 SQL Serverにも2フェーズコミットを行う仕組みがあるかもしれませんが、 ストアドプロシージャのreturnの値で処理が成功したかどうかを判断しています。 急いで書いたのでコードはまったく検証していません。(シンタックスエラーが出るかも) using System.Data.SqlClient; void hogehoge(){ SqlConnection con1 = new SqlConnection("~"); SqlCommand cmd1 = con1.CreateCommand(); cmd1.CommandText ="exec @result=Proc1"; cmd1.Parameters.Add("@result",SqlDbType.Int); cmd1.Parameters["@result"].Direction = ParameterDirection.ReturnValue; SqlConnection con2 = new SqlConnection("~"); SqlCommand cmd2 = con.CreateCommand(); cmd2.CommandText ="exec @result=Proc2"; cmd2.Parameters.Add("@result",SqlDbType.Int); cmd2.Parameters["@result"].Direction = ParameterDirection.ReturnValue; con1.Open(); SqlTransaction tran1 = con1.BeginTransaction(); cmd1.Transaction = tran1; con2.Open(); SqlTransaction tran2 = con2.BeginTransaction(); cmd2.Transaction = tran2; cmd1.ExecuteNonQuery(); cmd2.ExecuteNonQuery(); if(((int)cmd1.Parameters["@result"] == 0) && ((int)cmd2.Parameters["@result"] == 0)){ tran1.Commit(); tran2.Commit(); }else{ tran1.Rollback(); tran2.Rollback(); } con1.Close(); con2.Close(); }

terra5
質問者

お礼

わざわざありがとうございます。 ですが、質問の仕方が悪かったようです。お手数おかけしたのにすいません。 詳しくは補足に。

terra5
質問者

補足

やりたいことはその2フェーズコミットです。 私の説明不足でした。すいません。 2フェーズコミットは実現方法というか動作原理というかのためか、それで探すと更に情報が見つかりません。 MSDNなどは分散トランザクションという言葉で説明していましたので、それに合わせました。 SQL 7以降(6.5以降?)から可能になっているようです。 今のところわかった(つもり)なことは、分散トランザクション コーディネータ (MSDTC、Microsoft Distributed Transaction Coordinator)が2相コミットを実現している、 サービスとして存在していて、デフォルトでは手動起動になっている、 Enterprise Servicesを使用する(System.Enterprises)、 Connection.EnlistDistributedTransaction()を使うようだ といったところです。 また、MSDNは自動トランザクションを推奨しているようですが、それでは無理なケースが出てくると思われるので、手動で行う方法を探してます。 もっとも、自動ですらまだ動作させることができていませんが。 また、ストアドプロシジャは避けていただけるとありがたいです。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 分散トランザクションを開始できなかった

    [OSのVER]:2003server 同士 [SQLServerのVER]:SQLServer2000 StandardEdition SP3 はじめまして! 前のログ(http://www7.big.or.jp/~pinball/discus/sqls/26278.html)で でていたエラーメッセージ サーバー : メッセージ 7391、レベル 16、状態 1、プロシージャ [Microsoft][ODBC SQL Server Driver][SQL Server]OLE DB プロバイダ 'SQLOLEDB' は分散トランザクションを開始できなかったので、要求した操作は実行されませんでした。 [OLE/DB provider returned message: 指定されたトランザクション コーディネータに、新規トランザクションを参加できませんでした。] OLE DB エラー トレース [OLE/DB Provider 'SQLOLEDB' ITransactionJoin::JoinTransaction returned 0x8004d00a]。 と表示されます ビューや、MSDTC(http://support.microsoft.com/?scid=kb;ja;329332&spid=2852&sid=global) などすべてやってみましたがだめでした Enterprise Managerでリンクサーバーを設定して中身を確認する事もできました ビューでその別サーバーのDBを覗くこともできます ストアドでカーソルを使用しています DECLARE M_USER_CSR CURSOR FOR SELECT INPDATE FROM [別サーバ名].DB.dbo.xxxxxx WHERE INPDATE = @COMP_DATE -- システム更新日付比較 と、定義して FETCH NEXT FROM M_USER_CSR としたところで、エラーが表示されます 最初のフェッチではエラーがでず(一件目は正常に内容を取得してます) 二件目のフェッチでエラーがでます どのような解決方法がございますか? どうか教えてください よろしくお願いします ps:サーバー同士はドメイン管理されていません    ワークグループ管理のもと互いに信頼関係は結んでおります

  • SSISのトランザクションの設定がうまく出来ない

    パッケージ全体が成功すると パッケージ全体をコミットさせる、といった事をしたいのですが、 どうしてもうまく動作してくれません。。 ちなみに、以下の設定を実施しました。 ・パッケージ全体の[TransactionOption]を[Required] ・各タスクの[TransactionOption]を[Supported] ・パッケージ全体の[ProtectionLevel]を[DontSaveSensitive] #もちろん、[TransactionOption]を全て[Supported]にすると、 #問題無く動作します。 以下、エラーメッセージを纏めたものです。 -------------------------------------------------- 開始: XX:XX:XX エラー: 2008-08-XX XX:XX:XX コード: 0xC001A004 説明: 保持されている接続で互換性のないトランザクション コンテキストが指定されました。 この接続は別のトランザクション コンテキストで確立されています。 保持されている接続は 1 つのトランザクション コンテキストのみで使用できます。 エラー終了 -------------------------------------------------- エラー: エラー: 2008-08-XX XX:XX:XX コード: 0xC020801C ソース: フラットファイルよりTestTableへインポート OLE DB 変換先:TestTable [283] 説明: SSIS エラー コード DTS_E_CANNOTACQUIRECONNECTIONFROMCONNECTIONMANAGER。 エラー コード 0xC001A004 により、接続マネージャ "TestDB" に対する AcquireConnection メソッドの呼び出しが失敗しました。 このエラーの前に、AcquireConnection メソッドの呼び出しが失敗した理由の詳細が記載された エラー メッセージが報告されている可能性があります。 エラー終了 -------------------------------------------------- エラー: 2008-08-XX XX:XX:XX コード: 0xC0047017 ソース: フラットファイルよりTestTableへインポート DTS.Pipeline 説明: コンポーネント "OLE DB 変換先:TestTable" (283) が検証に失敗し、 エラー コード 0xC020801C が返されました。 エラー終了 -------------------------------------------------- このエラーが発生した際に、 「分散トランザクションを中止しています。」と、 パッケージの進行状況に表示されていることから、 分散トランザクション自体は動作しているように見えます。 以上より、 どなたか解決方法をご存知の方、ご教授頂けると幸いです!

  • .Net Frameworkのコードのデバッグ

    .Net Frameworkのコードをデバッグしたいのですが、ソース内へのステップインが出来ません。MSDNや他のWebサイトを参考にして、オプション設定とシンボルサーバーの登録は行いました。 https://referencesource.microsoft.com/setup.html マイコードで.Net Frameworkの関数をコールしている箇所でステップインしようとしても、中に入らずステップオーバーしてしまいます。何か設定が不足しているのでしょうか? MSのリファレンスソースのサイトからソースはDL出来るのですが、シンボルファイル(.pdb)は含まれていません。 開発環境はVisual Studio Professional 2017 です。

  • エクセルVBA_ADO「ファイアホースモードの間はトランザクションを開

    エクセルVBA_ADO「ファイアホースモードの間はトランザクションを開始できない」 最近、エクセルVBAからSQLサーバーを編集するプログラムの勉強をはじめ、以下のサイトを読みながらテストプログラムを走らせています。 http://www.happy2-island.com/access/gogo03/capter00306.shtml そして、以下のようなコードを走らせて見ると、「ファイアホースモードの間はトランザクションを開始できません」とのエラーが出ます。 コードを以下に記します((2)トランザクションを開始します←ここで上記のエラーが出ます) Sub prcAdoSQLServerDB() Dim adoCON As New ADODB.Connection Dim adoRS As ADODB.Recordset '(1)ADOを使いSQL ServerのDBを開きます adoCON.Open "Driver={SQL Server};" & _ "server=aaa\db; database=a1; uid=a; pwd=a;" 'レコードセットの作成(SELECT文の実行) Set adoRS = adoCON.Execute("select * from 明細") 'レコード追加のSQLを定義(フィールド名省略すると、nullを入れようとする) strsql = "INSERT INTO 詳細 (得意先コード) Values(000010)" '(2)トランザクションを開始します adoCON.BeginTrans '(3)レコード追加のSQLを実行します adoCON.Execute strsql '(4)SQL実行結果の判定 If Err.Number = 0 Then '(5)SQLが正常終了したら追加を反映します adoCON.CommitTrans Else '(6)SQLが異常終了したら追加の破棄とエラー内容の表示をします adoCON.RollbackTrans End If End Sub 何が原因なのでしょうか。

  • 排他ロックしたレコードが、別トランザクションから参照されてしまい困っています。

    SQL Server2000を使用し、 あるトランザクションで排他ロック(XLOCK)をかけたレコードが 他のトランザクションから共有ロックを使用し参照できてしまう状態は存在するのでしょうか? 排他ロックをかけたレコードが 他のトランザクションから参照できてしまい困っています。 現在、下記の環境で開発を行っております。 ・サーバ側 Windows Server2003 SQL Server2000(sp4) ・クライアント側 Windows Xp(sp3) jdk6.0 jdbc 3.0 Type4 以下が具体的な状況となります。 前提として、 ・二つのトランザクション(以下A、Bと表記します)が存在する。 ・AとBは別のユーザでコネクションを張っている。 ・autoCommitはfalseに設定している。 ・テーブルにプライマリキーやインデックスは張っていない。 ・レコードは10件。 ・分離レベルはREAD COMMITED (1)Aから、「SELECT * FROM TEST_TABLE WITH(XLOCK) 」を発行 (2)Bから、「SELECT * FROM TEST_TABLE」を発行 このような状況で、(1)、(2)の順で処理を行った場合に 私の認識では、(2)の検索時にタイムアウト等が発生するという認識です。 しかし、(2)のSQLは正常に終了し、(1)と同じデータが取得されてしまいます。 ◆その他、確認したこと ・(1)の処理直後に処理を停止し、Enterprise Managerでロックが取得されているか確認したところ、トランザクションAがすべてのレコードを排他ロック(X)していた。 ・(2)の処理直後にロックの状態を確認しても、やはりトランザクションAが、排他ロック(X)していた。 ・CSEを使いODBC経由で同様の操作を行った場合も同じ動作がおこる。 ・(1)WITH(XLOCK, TABLOCK)とすると(2)でデータが取得できなくなる。 ・(2)のSQLを「SELECT * FROM TEST_TABLE WHERE COLUMN01 > 0」のように指定するとタイムアウトする(期待通りの動き) ・(2)のSQLを「SELECT COLUMN01 FROM TEST_TABLE WHERE COLUMN01 > 0」のように指定すると、今度は、なぜか取得出来てしまう。 ・(1)と(2)の間にトランザクションAでUPDATEなどを行うと(COMMITはしない)(2)のSQLのWHERE句や取得するカラムに関係なく、(2)のSQLはタイムアウトする(当り前か。。。) いろいろ書きましたが、排他ロックされたレコードに 共有ロックはかけれないという認識なのですが、 そうではないのでしょうか? また、そうではない場合どういった場合に、 共有ロックが可能となるのでしょうか? SQL Serverの排他制御に詳しい方や 同じような現象に陥った方がいましたら、ご教授お願いします。

  • Microsoft .NET FRAMEWORKって何ですか?

    Microsoft .NET FRAMEWORKって、結局何ができて、何が便利なのか、わかりやすく説明していただけないでしょうか? Microsoftのホームページを見たりもしましたが、結局何なのかがわかりません。 何かのシステムのセールスポイントとして 「Microsoft .NETに対応したシステムです」 と書かれていたりもしますが、対応してると何が良いのでしょうか? 仕事で毎日メールやグループウェアは使っている。 程度の人にもわかるかなり噛み砕いた具体的な解説でお願い致します。

  • 手動または分散トランザクションモード…のエラー

      お世話になります。 開発言語:VisualBasic 6 sp6 OS :WindowsXP Pro sp3 DB :Microsoft SQL Server 2005 以下のコードはCommand1ボタンをクリックした時に実行される処理です。 処理内容は、テーブルAを読み、テーブルAの全てのレコードを順次読みながら テーブルBを検索し、テーブルBの"keyname"をprintします。 ※実際のプログラムではテーブルAを順次読むループの中で多数のテーブルへの  新規レコード追加、更新などを行っております。 Private Sub Command1_Click()   Dim objConn   As ADODB.Connection   Dim objRsA   As ADODB.Recordset   Dim objRsB   As ADODB.Recordset   Dim sSQL   As String   Set objConn = New ADODB.Connection   objConn.ConnectionString = cstrCon   objConn.Open   Set objRsA = New ADODB.Recordset   Set objRsB = New ADODB.Recordset   'トランザクション開始   objConn.BeginTrans   sSQL = "select * from テーブルA"   objRsA.Open strSQL, objConn   If objRsA.EOF = False Then     Do Until objRsA.EOF       sSQL = "select * from テーブルB where key = " & objRsA.Fields("key")       objRsB.Open strSQL, objConn    '←この行でエラー発生       Print objRsB.Fields("keyname").Value       objRsB.Close       objRsA.MoveNext     Loop   End If   objRsA.Close   'コミット   objConn.CommitTrans End Sub ↑の処理を実行すると「objRsB.Open strSQL, objConn」の行で以下の実行エラーになります。 "手動または分散トランザクションモードのため、新規接続を作成できません。" このエラーの原因が分からず自分でもいろいろ調べてみました。 以下のサイトも何度も見直してみましたがよく理解できませんでした。 http://support.microsoft.com/kb/234218/ja どこが間違っていて、どこを修正すればエラーが出なくなるのでしょうか? よろしくお願い致します。  

  • [統計]エクセルでの分散分析表の再現方法について

    質問を見ていただきまして有難うございます。 ただ今、分散分析表について勉強を始めたものです。 下記のURLに大変わかりやすい分散分析の説明があり、 それをエクセルで再現しようと思ったのですが、どうしても出来なかったため 質問させて頂きます。 <東北大学大学院農学研究科内HP> http://www.agri.tohoku.ac.jp/iden/toukei7.html 具体的には、URL内に2つの分散分析表があり、 1つ目の一元配置分散分析の表については、全く同じ結果が再現できたのですが、 2つ目の二元配置分散分析の表が再現できないのです。 エクセルは2010を使用しており、「分析ツール」から 「分散分析:繰り返しのある二元配置」と「分散分析:繰り返しのない二元配置」で 色々と試したのですが駄目でした。 要因が「趣味」と「学校の水準」と二つあるので、これをどのように 入力するかがポイントだと考えてはおるのですが、、、、 ご教示頂ければ大変ありがたいです。 何卒、宜しくお願い致します。

  • 統計学の不偏分散と変動係数について

    大学で出された問題です(特に課題というわけではありません) 1、次のデータの不偏分散を求めよ 7、11、9、8、11、5、7、2 2、変動係数の値はすべてのデータをスカラー倍しても変わらないのはなぜか説明せよ 1は自分で解いたところ答えが9.14・・・となりました。 解答は配られていないので間違っていないか不安です。 2は具体的な数値を入れて計算していくと確かに変わらないのですが 説明せよと言われるとどう説明してよいか分かりません。 優しく解説していただけると助かります。 お力添えをよろしくお願いいたします。

  • AccessのテーブルをSQL Serverに自動インポートする方法について

    現在SQL Server2005を使用しております。 別のサーバー内でAccessのテーブルデータが定期的に更新されており、 このデータを利用したシステムをSQL Server上で作ろうと考えています。 手動でSQL ServerにAccessのテーブルデータをインポートするやり方は分かりましたが、(データ更新の為に)定期的にインポートする方法がわかりません。 どのように実現すればよいか、サンプルや参考になるHPがありましたら 是非教えていただけないでしょうか?