最初にEF5コードと.NET4.5を使用するMVCプロジェクト。
単一のトランザクションでdbContextとSimpleMembershipProviderをラップする方法を探していました。TransactionScopeを使用しようとしましたが、メンバーシッププロバイダーが別の接続を開くため、例外が発生します(サーバー'servername'のMSDTCは使用できません)。
したがって、代わりにObjectContext.Connection.BeginTransactionを使用できます。メンバーシッププロバイダーはトランザクションの一部にはなりませんが、失敗した場合にトランザクションがコミットされない場所にメンバーシッププロバイダーを配置することを目的としています。
Book bk1 = default(Book);
Book bk2 = default(Book);
object obc = (IObjectContextAdapter)dbContext;
obc.ObjectContext.Connection.Open();
using (tx == obc.ObjectContext.Connection.BeginTransaction) {
bk1 = new Book {
Name = "Book 1 Name",
Location = "USA"
};
dbContext.Books.Add(bk1);
dbContext.SaveChanges();
bk2 = new Book {
Name = "Book 2 Name. Book one Id is: " + bk1.Id,
Location = "USA"
};
dbContext.Books.Add(bk2);
dbContext.SaveChanges();
// this is not part of the transaction,
// however if it trhows an exception the transaction is aborted.
// I'm assuming that if we got here, the commit won't fail...
// But is it really true?
WebSecurity.CreateUserAndAccount("username", "123456");
tx.Commit();
}
とにかく、上記のコードに基づいて:
- WebSecurity.CreateUserAndAccountが失敗すると、すべてが失敗します。これは予想どおりです。
- SaveChangesメソッドのいずれかが失敗した場合、CreateUserAndAccountが実行されるポイントに到達しないため、もう一度すべてが失敗します。
このすべてが私に質問をもたらします:それは安全ですか?私が意味するのは:
DbContext.SaveChangesを正常に実行した後、「Commit」メソッドが(何らかの理由で失敗した)例外をスローする可能性はありますか?それが発生した場合、プロバイダーはトランザクションの一部ではないため、孤立したユーザーになってしまいます。
これについてのコメントやアドバイスに感謝します。
クイックノート:独自の接続プロパティを使用する代わりにdbContextをIObjectContextadapterにキャストする必要がある理由を説明するこの素晴らしい記事がありますが、もう見つかりません。