問題タブ [transactionscope]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c# - 一部のマシンでは、TransactionScope が自動的に MSDTC にエスカレートしますか?
私たちのプロジェクトでは、TransactionScope を使用して、データ アクセス レイヤーがトランザクション内でそのアクションを確実に実行するようにしています。エンド ユーザーのマシンで MSDTC サービスを有効にする必要がないことを目指しています。
問題は、半分の開発者マシンで、MSDTC を無効にして実行できることです。残りの半分は有効にする必要があります。そうしないと、"[SERVER] の MSDTC は利用できません" というエラー メッセージが表示されます。
本当に頭を悩ませており、ADO.NET トランザクション オブジェクトに基づいて自作の TransactionScope のようなソリューションに戻すことを真剣に考えています。これは正気ではないように思えます - 私たちの開発者の半分で動作する (そしてエスカレートしない) 同じコードが、他の開発者ではエスカレートします。
トランザクションが DTC にエスカレートされる理由を追跡するためのより良い回答を期待していましたが、残念ながらそうではありません。
問題を引き起こすコードのサンプル ビットを次に示します。エスカレートしようとするマシンでは、2 番目の connection.Open() でエスカレートしようとします (そして、その時点で開かれている他の接続はありません)。
私たちは本当に掘り下げて、これを理解しようとしました。これが動作するマシンに関する情報は次のとおりです。
- 開発 1: Windows 7 x64 SQL2008
- 開発 2: Windows 7 x86 SQL2008
- 開発 3: Windows 7 x64
SQL2005SQL2008
動作しない開発者:
- 開発 4: Windows 7 x64、
SQL2008SQL2005 - 開発 5: Windows Vista x86、SQL2005
- 開発 6: Windows XP X86、SQL2005
- 自宅の PC : Windows Vista Home Premium、x86、SQL2005
問題を突き止めようとして、Microsoft Update から入手できるすべてのパッチがすべてのマシンに適用されていることを付け加えておきます。
更新 1:
- http://social.msdn.microsoft.com/forums/en-US/windowstransactionsprogramming/thread/a5462509-8d6d-4828-aefa-a197456081d3/は、同様の問題について説明しています... 2006年に戻って!
- http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope%28VS.80%29.aspx - そのコード サンプルを読んでください。ネストされた 2 番目の接続 (2 番目の SQL サーバーへの、実際には) DTC にエスカレートします。 私たちのコードではこれを行っていません - 別の SQL サーバーも別の接続文字列も使用しておらず、ネストされたセカンダリ接続も開いていません - DTC へのエスカレーションがあってはなりません。
- http://davidhayden.com/blog/dave/archive/2005/12/09/2615.aspx (2005 年以降) では、SQL2000 に接続するときに DTC へのエスカレーションが常に発生する方法について説明しています。SQL2005/2008 を使用しています
- http://msdn.microsoft.com/en-us/library/ms229978.aspxトランザクション エスカレーションに関する MSDN。
MSDN のトランザクション エスカレーション ページには、次の条件によりトランザクションが DTC にエスカレートされると記載されています。
- 単一フェーズの通知をサポートしていない少なくとも 1 つの永続的なリソースが、トランザクションに登録されています。
- 単一フェーズの通知をサポートする少なくとも 2 つの永続的なリソースが、トランザクションに登録されます。たとえば、単一の接続を登録しても、トランザクションは昇格されません。ただし、データベースへの 2 番目の接続を開いてデータベースを参加させると、System.Transactions インフラストラクチャは、それがトランザクション内の 2 番目の永続的なリソースであることを検出し、MSDTC トランザクションにエスカレートします。
- トランザクションを別のアプリケーション ドメインまたは別のプロセスに「マーシャリング」する要求が呼び出されます。たとえば、アプリケーション ドメインの境界を越えたトランザクション オブジェクトのシリアル化です。トランザクション オブジェクトは値によってマーシャリングされます。つまり、アプリケーション ドメインの境界を越えて渡そうとすると (同じプロセスであっても)、トランザクション オブジェクトがシリアル化されます。Transaction をパラメーターとして受け取るリモート メソッドで呼び出しを行うことによって、トランザクション オブジェクトを渡すことができます。または、リモート トランザクション サービス コンポーネントへのアクセスを試みることができます。これにより、トランザクション オブジェクトがシリアル化され、アプリケーション ドメイン全体でトランザクションがシリアル化される場合と同様に、エスカレーションが発生します。これは分散されており、ローカル トランザクション マネージャーはもはや適切ではありません。
私たちは#3を経験していません。#2は、一度に1つの接続しかなく、単一の「永続的なリソース」に対しても接続されるため、発生していません。#1が起こる方法はありますか?単一フェーズ通知をサポートしない原因となる SQL2005/8 構成はありますか?
更新 2:
個人的に、全員の SQL Server バージョンを再調査しました。「Dev 3」には実際には SQL2008 があり、「Dev 4」には実際には SQL2005 があります。同僚を二度と信用しないように教えてくれます。;) このデータの変更により、問題が見つかったと確信しています。SQL2008 には、SQL2005 にはない大量の素晴らしい機能が含まれているため、SQL2008 の開発者はこの問題に直面していませんでした。
また、SQL2005 をサポートする予定であるため、これまでのように TransactionScope を使用することはできず、TransactionScope を使用したい場合は、単一の SqlConnection オブジェクトを渡す必要があることもわかります...これは、SqlConnection を簡単に渡すことができない状況では問題があるようです...グローバル SqlConnection インスタンスのにおいがするだけです。ピュー!
アップデート 3
ここで質問を明確にするために:
SQL2008:
- 1 つの TransactionScope 内で複数の接続を許可します (上記のサンプル コードで示されているように)。
- 警告 #1: これらの複数の SqlConnections がネストされている場合、つまり、2 つ以上の SqlConnections が同時に開かれている場合、TransactionScope はすぐに DTC にエスカレートします。
- 警告 #2: 追加の SqlConnection が別の「永続的なリソース」 (つまり、別の SQL Server) に対して開かれると、すぐに DTC にエスカレートされます。
SQL2005:
- 1 つの TransactionScope 期間内に複数の接続を許可しません。2 番目の SqlConnection が開かれるとエスカレートします。
更新 4
この質問をさらに便利にするために、そしてより明確にするために、SQL2005を単一の SqlConnection
.
SqlConnection.Open()
これは私には壊れているように見えますが、へのすべての呼び出しが接続プールから取得されている かどうかは理解できると思います。
「しかし、なぜこれが起こるのでしょうか?」 接続が開かれる前にその接続に対して SqlTableAdapter を使用すると、SqlTableAdapter は接続を開いたり閉じたりして、トランザクションを効果的に終了します。
したがって、基本的に、SQL2005 で TransactionScope を正常に使用するには、最初の TransactionScope がインスタンス化されてから不要になるまで、何らかのグローバル接続オブジェクトを開いたままにしておく必要があります。グローバル接続オブジェクトのコード臭に加えて、最初に接続を開いて最後に閉じることは、接続をできるだけ遅く開き、できるだけ早く閉じるというロジックに反します。
c# - System.Transactions.TransactionScope.Commit() が呼び出されなくてもデータがコミットされた
System.Transactions.TransactionScope
例外がスローされ、最も外側のスコープでコミットが呼び出されなかったにもかかわらず、どのような状況でコードが静止コミットにラップされる可能性がありますか?
にラップされたトップレベルのメソッドがあり、同じようにusing (var tx = new TransactionScope())
使用するメソッドを呼び出します。TransactionScope
関連付けられたテーブルアダプターで型指定されたデータセットを使用しています。何らかの理由で、アダプターのコマンドが登録されていない可能性がありますか? アンビエント TransactionScope に参加しているかどうかを確認する方法を知っている人はいますか?
c# - 高度な System.Transactions デバッグ
の実行時の動作に関するプロファイリング/ロギング/デバッグ情報を取得するためのヒント、トリック、または方法はありSystem.Transactions.TransactionScope
ますか?
System.Transactions.TransactionScope
例外がスローされ、TransactionScope.Commit()
呼び出されないアプリケーションを使用しているにもかかわらず、データをデータベースにコミットしているアプリケーションがあります。
TransactionScope
コマンド (型指定されたデータ アダプター) がアンビエント トランザクションを登録しているかどうかを確認するために、実行時にクエリを実行できる他のクラスのイベントまたは詳細があるかどうか疑問に思っていました。
Reflector の使用を検討した結果、名前空間が役立つSystem.Transactions.dll
と思いますが、例を教えていただければ幸いです。System.Transactions.Diagnostics
c# - MS States のリモート プロシージャ トランス オプションは、次のバージョンの SQL SERVER で削除されます
ここで聞いていいのかわからない… ネットで答えを探したけどだめだった… だからここで運を試してみたかった。
Microsoft Web サイトhttp://msdn.microsoft.com/en-us/library/ms189322(SQL.90).aspxからの抜粋を次に示します。
remote proc trans オプション
リモート プロシージャ トランス オプションを使用して、Microsoft 分散トランザクション コーディネーター (MS DTC) トランザクションを介してサーバー間プロシージャのアクションを保護します。remote proc trans を 1 に設定して、トランザクションの ACID (アトミック、一貫性、分離、耐久性) プロパティを保護する MS DTC 調整分散トランザクションを提供します。このオプションを 1 に設定した後に開始されたセッションは、構成設定をデフォルトとして継承します。
この機能は、Microsoft SQL Server の次のバージョンでは削除される予定です。新しい開発作業でこの機能を使用することは避け、現在この機能を使用しているアプリケーションを変更することを計画してください。
このオプションは、リモート ストアド プロシージャを使用するアプリケーション用の以前のバージョンの Microsoft SQL Server との互換性のために提供されています。リモート ストアド プロシージャ コールを発行する代わりに、sp_addlinkedserver を使用して定義されたリンク サーバーを参照する分散クエリを使用します。
これは、トランザクション スコープ オブジェクトが MSDTC に昇格するシナリオでの使用を避ける必要があるということですか?
注 : これは SQL Server 2005 のメッセージですが、SQL Server 2008 でも同じメッセージが表示されます。
.net - TransactionScopeとMSDTCを使用する場合の一般的な落とし穴
TransactionScopeを使用して作業を始めたばかりですが、デバッグに永遠にかかる予期しないことが常に発生していることがわかりました。
これらのリストを統合することは、これらの「奇妙なエラー」の状況に加えて、プラットフォームの奇妙さに関する知識を広げるのに最適だと思います。
トランザクションスコープをどのように使用するかについてのコンテキスト:
- ウェブアプリケーション
- 複数のWebサーバー、アプリケーションサーバー、SQLサーバー
- トランザクションは主にデータベーストランザクションになりますが、MSMQに書き込むために昇格されるものもあります。
oracle - 「非同期」コミットを処理するための良い方法は何ですか?
ODP.NETを使用してOracleデータベースからデータを読み取るWCFサービスがあります。このサービスはデータベースにも書き込みますが、間接的に、すべての更新と挿入は、 TransactionScopeでラップするCOM+を介してアクセスするビジネスロジックの古いレイヤーを介して実行されるためです。古い層は、ODP.NETではなくODBCを介してOracleに接続します。
私が抱えている問題は、Oracleが2フェーズコミットを使用し、古いビジネスレイヤーがODP.NETではなくODBCを使用しているため、データが実際にサービスレイヤーからの読み取りに使用できるようになる前にトランザクションが返されることがあることです。TransactionScope.Commit()
StackOverflowでもこのような問題を抱えているJavaユーザーに関する同様の投稿があります。
Oracleの担当者は、この問題について私ができることはあまりないと投稿しました。
これは、OLETx ITransaction :: Commit()メソッドの動作が原因である可能性があります。2PCのフェーズ1(つまり、準備フェーズ)の後、すべてが成功 すると、リソースマネージャーが実際にコミットしていなくても、コミットを返すことができます。。結局のところ、成功した「準備」は、リソースマネージャーがこの時点以降に任意に中止できないことを保証するものです。したがって、リソースマネージャーがMSDTCから「コミット」通知を受信しなかったためにコミットできなかった場合でも(通信障害などが原因で)、コンポーネントのコミット要求は正常に返されます。テーブルから行をすぐに選択すると、選択を実行した後、データベースで実際のコミットが発生する場合があります。したがって、読み取りセマンティクスが一貫しているため、selectには新しい行が表示されません。「フェーズ1の成功後に成功をコミットする」最適化はMSDTCの実装の一部であるため、Oracleではこれについて何もできません。
だから、私の質問はこれです:
2PCの2番目の部分が実際にいつ発生するかを把握する際に発生する可能性のある遅延(タイトルの「asyc」)の問題に対処するにはどうすればよいですか。したがって、(間接的に)挿入したデータが実際に選択可能であると確信できます。Commit()
呼び出しが戻った後?
大規模なシステムは、データをすぐに読み取る準備ができていない可能性があるという事実にどのように対処しますか?
sql-server-2008 - .Net 2.0アプリケーションでのトランザクション-何を使用しますか?
.Net 2.0アプリケーションで作業しており、データベーストランザクションをコードでラップする必要があります。バックエンドはSQLServer2008です。
私は数年間.netを離れていましたが、最後にトランザクション処理を行ったのは、サービスされたコンポーネントを使用した.Net1.1でした。私はTransactionScopeについて知っていて、それが今のことを行うのに良い方法かどうか疑問に思っていました。
また、.Net 3.5では、これを行う他の方法があると思います。たとえば、WCFを使用しますか?誰かが私を1つか2つの記事に向けることができるかどうか疑問に思っています。どうもありがとう。
vb.net - TransactionScopeをインスタンス化するとnullが返されます
TransactionScopeインスタンスを作成するVB.NETコードがいくつかあります。
私のアプリケーションは、「オブジェクト参照がオブジェクトのインスタンスに設定されていません」という新しいTransactionScopeの作成の呼び出しで例外をスローしています。例外は、開発マシンまたはテストマシンではスローされません。顧客の生産機械だけで、理由はわかりません。この行の直前と直後にデバッグ行を配置したので、この行が問題の原因であると確信しています。
アプリケーション全体でTransactionScopesを使用しており、これがクライアントマシンで例外をスローする唯一の場所です。
「コールデータをコントラクトに関連付けようとしています」がログに書き込まれ、次のログエントリは「オブジェクトのインスタンスに設定されていないオブジェクト参照」です。
コードをトランザクションから移動すると、コードは正常に機能します。
私はこれに4日間苦労していて、近づいていません。
ado.net - TransactionScope内でADO.Netトランザクションを使用していますか?
私は TransactionScope について読んでいて、ADO.Net トランザクションとの相互運用性について質問がありました。現在、それぞれがストアド プロシージャを呼び出し、独自の個々のトランザクションを開始およびコミットするいくつかのデータ アクセス メソッドがあります。簡単な定型的なもので、メソッドは次のようになります。
私は物事を少し単純化しましたが、あなたはその考えを理解しています。
これらのクラス メソッドのうち 2 つを連続して呼び出し、ビジネス レイヤーからチームとしてコミットまたはロールバックする必要があります。データ メソッドを変更できないため、2 つの呼び出しを TransactionScope ブロックに入れることを考えていました。
これを行う場合、TransactionScope を作成するときにどのようなパラメーターを使用すればよいですか? 私はすでに TransactionScopeOption.RequiresNew オプションを使用してこれを試しましたが、うまくいくように見えますが、それは私が実験しているだけであり、それが正しいかどうかはわかりません。(ここで、これらは同じ SQL サーバー上で実行される SQL トランザクションのみであることに注意してください。)
TransactionScope には、COM+ トランザクションを処理するためのコンストラクター オプションがあることがわかりました。私は ADO.Net トランザクションを使用しているため、ここで関係がありますか? アドバイスをありがとう。
c# - TransactionScopeは、2番目のサービスエラーがあっても部分的な更新を許可します
関連する質問と実装された提案をよく調べましたが、.NETTransactionScopeにまだ問題があります。
メソッドから2つのWCFサービスを呼び出していますが、2番目のサービスエラー(この場合は意図的に)が発生しても、最初のサービスはロールバックされません。問題を実証するための簡単なテストアプリケーションを作成しました。
呼び出しメソッドは次のとおりです。
最初のサービスは次のようになります(接続は匿名になります):
また、2番目のサービスは、データベース内の別のフィールドを更新することを除いて、最初のサービスと同じです。
1)エラーを強制せずにこれを実行すると、すべてのフィールドが正常に更新されます。
2)これを実行して2番目のサービスでエラーを強制すると、最初のサービスからの更新がデータベースにコミットされ、2番目のサービスがロールバックされます(エラーはExecuteNonQueryステートメントの後であります)。
このサンプルコードは、基本的にここにある例に従います:http: //msdn.microsoft.com/en-us/library/system.transactions.transactionscope.aspx
また、他の関連する質問で推奨されているExplicitUnbindを追加しました。
ご提案は大歓迎です。必要に応じて、さらに情報を追加させていただきます。
追加情報
配布された識別子は常に00000000-0000-0000-0000-000000000000のようです-これが手がかりかどうかはわかりません。
これが分散IDとローカルIDのdubug出力です(この順序で)
現在のトランザクションは00000000-0000-0000-0000-000000000000-f6446876-496d-488c-a21c-1e4c4295d50c:8
現在のトランザクションは00000000-0000-0000-0000-000000000000-7edd5ba3-7f5a-42af-b9ca-37b3862c26a7:2です。
現在のトランザクションは00000000-0000-0000-0000-000000000000-6fa0e3f7-b655-40ad-8bdd-f0670de79a49:2です。
トランザクションは、私のサンプルアプリのaspxページの背後にあるコードを介して開始されています。