トランザクション内の SQL バッチ中止エラーから回復しますか?代替?
-
19-09-2019 - |
質問
優先度の低いデータの挿入中にエラーが発生してもトランザクションの実行を続行する方法を探しています。実際にネストされたトランザクションが解決策になる可能性があるように思えますが、SQL Server 2005/2008 ではサポートされていません。別の解決策は、エラーが重大かどうかを判断するロジックを用意することですが、それも不可能のようです。
私のシナリオの詳細は次のとおりです。
データは ADO.NET/C# を使用してデータベースに定期的に挿入されます。データの一部は重要ですが、問題なく欠落しているデータもあります。挿入が完了すると、データに対していくつかの計算が行われます。(重要と非重要の両方) このプロセス全体はトランザクション内にあるため、すべてが同期された状態に保たれます。
現在、トランザクション セーブ ポイントが使用され、非重要な挿入中に発生する例外に対して部分的なロールバックが行われます。ただし、これは「バッチ中止」エラーでは機能せず、トランザクション全体が自動的にロールバックされます。一部のエラーは重大であることは理解していますが、キャストの失敗などは SQL Server によってバッチ中止エラーとみなされます。(バッチエラーに関する情報) これらのエラーが優先度の低いデータで発生した場合に、挿入全体がダウンしないようにしようとしています。
私が説明していることが不可能な場合は、データの整合性を達成するための代替方法を検討するつもりですが、重要ではない挿入の失敗は許容します。
ご協力いただきありがとうございます。
解決
残念ながら、あなたが説明したように行うことはできません(ここではネストされたトランザクションの完全なサポートが重要です)。過去にこの問題を回避するために使用されてきたものとして、私が考えることができるいくつかの方法があります。
おそらく最善の選択肢は、コマンドを重要なコマンドと重要でないコマンドに分けて、個別に実行できるようにすることです。当然、これには相互に順序に依存しないことが必要になります。
メッセージング ベースのアプローチを使用することもできます (「 サービスブローカー) ここでは、プライマリ コマンドをインラインで実行し、プライマリ以外のコマンドを後で/個別に実行するためにキューにプッシュします。キューへのプッシュはバッチ内でトランザクション処理されますが、キューからポップオフするときのコマンドの実行は別個に実行されます。これも、相互に順序に依存しないことが必要です。
順序に依存する場合は、すべてにメッセージング アプローチを使用できます。これにより、順序が保証され、操作ごとに個別のメッセージを持つことができ、それらを (会話グループを介して) グループ化すると、それらをキューから順番に取り出して使用することもできます。操作の「タイプ」ごとに個別のトランザクション (つまり、プライマリー vs.非プライマリ)。すべてのグループ化されたメッセージを 1 つの自律的な操作にする必要がある場合、これには特別なコーディングが必要になりますが、実行することは可能です。
このオプションはひどいオプションなので言及することさえ躊躇しますが、完全に開示しておくと、これが適切だと思われる場合は、ご自身の裁量で検討していただければと思います (ただし、ほぼすべてのシナリオに適用できるアーキテクチャではないことは明らかです)。xp_cmdshell を使用してコマンド ラインを呼び出し、重要ではないタスクに対して sqlcmd/osql を実行することもできます。この sqlcmd の実行は、実行しているモジュールとは別のトランザクションで行われ、xp_cmdshell の失敗を単純に無視することで、プライマリ タスクが許可されるはずです。続行するバッチ。
それらはいくつかのアイデアです...
他のヒント
あなただけの重要な部分のためのトランザクションを使用して、一時的な場所にあなたのインポートを行うことができます。一時場所がロードされたら、任意の非致命的なエラーを吸収した、あなたは、単一のトランザクションでその最終目的地にデータをコピーすることができます。あなたがやっている仕事が、潜在的に実行可能な選択肢に性質によって異なります。