2017-05-05 21 views
2

レコードを追加する必要があるシナリオがあります。レコードが追加された場合はクラウド上にリソースを作成し、リソース識別子でテーブル内のレコードを更新しますリソースがクラウド上に作成されている場合だから、彼らは3つの操作であり、そのうちのどれかが成功しないとすべてを元に戻したい。単一トランザクションで複数の操作を実行する方法

私は一度に複数のDbオペレーションのためのTransactionScopeを持っていますが、私はこれを達成する方法が不思議ですか?あなたの助けに感謝!

編集

PS:そのような操作の任意の数があるかもしれませんが - シーケンスの10以上を言うと、彼らも、DB操作に関連しない場合があります。彼らはただ10個のファイルを順番に作成することができます。そのため、ファイルの作成に失敗した場合、以前のファイルはすべて削除/元に戻す必要があります。

+0

DBの両方がシングルDBで動作し、同じ接続で動作していますか? – Amit

答えて

0

あなたはAzureをクラウドとして使用していると仮定します。 トランザクションをサポートするには、 -


1.トランザクションをサポートするAzure上の弾性データベース。
2.分散トランザクションを利用するには、.NET Framework 4.6.1以上が必要です。

私は、トランザクション・スコープが適用される考慮3つの手順を破ることができますあなたのケースで今https://docs.microsoft.com/en-us/azure/sql-database/sql-database-elastic-transactions-overview

を通過することをお勧めします。

  1. テーブルにレコードを追加 -
    これは、私は推測する心配が失敗していない場合。
  2. クラウドでリソースを作成する -
    これが失敗すると、追加されたレコードはロールバックされます。
  3. リソースIDが作成されたテーブルのレコードを更新します。
    これが失敗すると、1ステップがロールバックされます。

トランザクションスコープの終了後、3番目のステップで追加されたレコードが存在することを確認する必要があります。そうでない場合は、リソースの削除を手動でロールバックする必要があります。

+0

あなたのお返事ありがとうございました。私はプログラミングの一般的な考え方を考えていて、どのデータベースにも特有ではない。私は私の質問を更新しました。一見してください。 –

2

コマンドパターンのやり方はどうですか?完璧なコマンドパターンの実装ではないかもしれませんが、非常に近いものです。以下を参照してください:

public interface ICommand { 
    ICommandResult Execute(); 
    ICommandResult Rollback(); 
} 

public interface ICommandResult { 
    bool Success { get; set; } 
    object Data { get; set; } 
    Exception Error { get; set; } 
} 

public class CommandResult : ICommandResult { 
    public bool Success { get; set; } 
    public object Data { get; set; } 
    public Exception Error { get; set; } 
} 

public class AddToDBCommand : ICommand { 
    private ICommandResult result; 
    private int newRecordId; 

    public AddToDBCommand(<params_if_any>) { 
     result = new CommandResult(); 
    } 

    public ICommandResult Execute() { 
     try { 
      // insert record into db 
      result.Success = true; 
      result.Data = 10; // new record id 
     } 
     catch (Exception ex) { 
      result.Success = false; 
      result.Error = ex; 
     } 
     return result; 
    } 

    public ICommandResult Rollback() { 
     try { 
      // delete record inserted by this command instance 
      // use ICommandResult.Data to get the 'record id' for deletion 
      Console.WriteLine("Rolling back insertion of record id: " + result.Data); 
      // set Success 
     } 
     catch(Exception ex) { 
      // set Success and Error 
      // I'm not sure what you want to do in such case 
     } 
     return result; 
    } 
} 

同様に、クラウドリソースを作成してdb内のレコードを更新するためのコマンドを作成します。メインコードでは、ICommandオブジェクトのコレクションを保持し、それぞれを実行できます。それが収集し、各コマンドにRollbackを呼び出しながら後方ループで現在のコマンドインデックスを記録し、その後Success = falseを返す場合

var commands = new List<ICommand> 
{ 
    new AddToDBCommand(<params_if_any>), 
    new AddToCloudCommand(<params_if_any>), 
    new UpdateInDBCommand(<param_if_any>) 
}; 

は、その後のループで、あなたは、Executeを呼び出すことができます。

+0

ありがとうniksofteng、非常に有望に見えます。私はこれを試してみるつもりで、ここですぐに更新します。 –

関連する問題