質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.53%
Entity Framework

Entity Frameworkは、.NET Framework 3.5より追加されたデータアクセス技術。正式名称は「ADO.NET Entity Framework」です。データベースエンジンに依存しておらず、データプロバイダの変更のみで様々なデータベースに対応できます。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

Azure

Azureは、マイクロソフトのクラウド プラットフォームで、旧称は Windows Azureです。PaaSとIaaSを組み合わせることで、 コンピューティング・ストレージ・データ・ネットワーキング・アプリケーションなど多くの機能を持ちます。

Q&A

解決済

2回答

1325閲覧

AzureSQLServer利用時のトランザクション・リトライ・catch処理について

merry93

総合スコア17

Entity Framework

Entity Frameworkは、.NET Framework 3.5より追加されたデータアクセス技術。正式名称は「ADO.NET Entity Framework」です。データベースエンジンに依存しておらず、データプロバイダの変更のみで様々なデータベースに対応できます。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

Azure

Azureは、マイクロソフトのクラウド プラットフォームで、旧称は Windows Azureです。PaaSとIaaSを組み合わせることで、 コンピューティング・ストレージ・データ・ネットワーキング・アプリケーションなど多くの機能を持ちます。

0グッド

0クリップ

投稿2022/10/03 00:14

編集2022/10/03 17:58

前提

VS2022、c#、EF6、Azure SQL Serverでよくあるデータベース情報の取得・更新の実装をしています。
(Visual Studio 2022、c#.NET MVC5 アプリを.NET Framework 4.7.2、Entity Framework 6を利用して開発予定(変更の可能性あり)です。)

実現したいこと

更新時のトランザクションやリトライ処理・エラー発生時のcatchについて正しい実装を知りたい。

発生している問題・エラーメッセージ

特になし

該当のソースコード

C#

1●リトライ設定 2SetExecutionStrategy( 3"System.Data.SqlClient", 4() => new SqlAzureExecutionStrategy(10, TimeSpan.FromSeconds(30))); 5 6 7●更新処理 8var executionStrategy = new SqlAzureExecutionStrategy(); 9 10executionStrategy.Execute( 11 () => 12 { 13 using (var db = new BooksDbContext()) 14 { 15 try 16 { 17 using (var tran = db.Database.BeginTransaction()) 18 { 19 try 20 { 21 db.Books.Add(new Book { Title = "日本の歴史1", HakkoYear = 2019 }); 22 db.Books.Add(new Book { Title = "日本の歴史2", HakkoYear = 2020 }); 23 db.SaveChanges(); ←① 24 25 db.Database.ExecuteSqlCommand( 26 "UPDATE Book SET Title = '日本の歴史1_1' WHERE Id = 1" ←② 27 ); 28 29 db.Books.Add(new Book { Title = "日本の歴史3", PublishedYear = 2022 }); 30 31 db.SaveChanges(); ←③ 32 33 tran.Commit(); 34 } 35 catch (SqlException e)[A]SQLに誤りがあった場合等のエラー 36 { 37 Console.WriteLine("SqlException1" + e.ToString()); 38 } 39 } 40 } 41 catch (SqlException e)[B]Azureへの接続自体ののエラー(権限なし等) 42 { 43 Console.WriteLine("SqlException2" + e.ToString()); 44 } 45 } 46 });

試したこと

Azureはリトライ処理が必須とのことで一通り実装しましたが、
トランザクションとリトライとキャッチ処理がバラバラのサンプルを合わせました。
(1)例中の①②③の3回の更新処理でもし一時的なエラーが発生した場合はリトライ設定どおりのリトライを実行してほしい
(2)SQLエラーや致命的な接続でエラーの場合はcatchしてしかるべき処理をして終了させたい
というのが希望の動作です。

それと、このコードで一時エラーの場合のリトライ処理が本当に実行されているか確認する方法が分からないです。
一時的なエラーを故意に作り出すことも難しいような、、。

実装方法や確認方法についてご教授いただけますと幸いです。

補足情報(FW/ツールのバージョンなど)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2022/10/03 00:29 編集

https://teratail.com/questions/6uwlcqwrrap7qi <= 質問は編集できるので、無駄にスレッドを増やすのではなく、先のスレッドを編集するようにしてください。無駄にスレッドを増やすのは閲覧者の迷惑になると認識してください。やってしまってからでは何ともならないので先のスレッドは運営に削除依頼を出してください。
退会済みユーザー

退会済みユーザー

2022/10/03 00:23

何を何で作っているか書きましょう。 (例: Visual Studio 2022 で ASP.NET MVC5 アプリをターゲットフレームワーク .NET Framework 4.8 で作っています)
merry93

2022/10/03 00:30

自宅Wi-Fi不調で対応している間に誤って投稿してしまいました。 投稿削除依頼は提出済みです。本当に申し訳ございません。 Visual Studio 2022、c#.NET MVC5 アプリを.NET Framework 4.7.2、Entity Framework 6を利用して開発予定です。 ※環境調査段階ですので変更の可能性もあります。
退会済みユーザー

退会済みユーザー

2022/10/03 00:34

> Visual Studio 2022、c#.NET MVC5 アプリを.NET Framework 4.7.2、Entity Framework 6を利用して開発予定です。 質問欄を編集して、追加情報として追記願います。ここは「質問への追記・編集の依頼」を行う場で、初期画面では閉じているので見ない人も多々います。
退会済みユーザー

退会済みユーザー

2022/10/03 02:20

質問のコードのインデントが乱れてます。直してください。インデントされてないコードは質問者さん自身でも読む気がしないのでは? 回答者・閲覧者はなおさらです。
merry93

2022/10/03 03:27

ご指摘ありがとうございます。 やり方がよく分からずでしたが、ソースコードの部分は修正(そもそもコード用の投稿にしていませんでした)しました。
guest

回答2

0

ベストアンサー

クラウドの DB との接続で発生しやすい一時的な接続エラーに対応するという話でしたら、EF6 には接続回復性機能というのがあって、失敗した SQL クエリを再試行するプロセスを自動化できます。

詳しくは以下の Microsoft のチュートリアルを見てください。

チュートリアル: ASP.NET MVC アプリで Entity Framework で接続の回復性とコマンド インターセプトを使用する

https://learn.microsoft.com/ja-jp/aspnet/mvc/overview/getting-started/getting-started-with-ef-using-mvc/connection-resiliency-and-command-interception-with-the-entity-framework-in-an-asp-net-mvc-application

"クラウド サービスにアクセスするときの接続の問題の多くまたは大部分は一時的であり、短時間で解決されます。 そのため、データベース操作を試して、通常は一時的なエラーの種類を取得すると、しばらくしてから操作を再試行すると、操作が成功する可能性があります。 一時的なエラーを処理する場合は、ユーザーが自動的に再試行し、ほとんどのエラーを顧客に見えないようにすることで、ユーザーにとってはるかに優れたエクスペリエンスを提供できます"

・・・と言うことです。

チュートリアルに従ってやってみましたが、試験する方法も詳しく書いてあって、大変役に立ちました。

投稿2022/10/03 00:40

編集2022/10/03 00:45
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

merry93

2022/10/03 01:59

とても丁寧に回答してくださりありがとうございました。 ご案内いただいた内容を勉強させていただきます。 ちなみにその対応は、 SetExecutionStrategy( "System.Data.SqlClient", () => new SqlAzureExecutionStrategy(10, TimeSpan.FromSeconds(30))); で設定するリトライとはまた別のものなのでしょうか?
退会済みユーザー

退会済みユーザー

2022/10/03 02:12

SetExecutionStrategy は紹介したチュートリアルで使ってます。使い方は違いますが。
退会済みユーザー

退会済みユーザー

2022/10/03 02:28 編集

ひょっとして、そもそものやりたいことは、複数の INSERT 処置をトランザクションに束ねて、失敗したらロールバックしたいという話なのですか? であれば、EF6 には一つの SaveChanges ではデフォルトでロールバックされるようになっているので、質問に書いてあるようなことはしなくて済むのですが。 トランザクションの使用 https://learn.microsoft.com/ja-jp/ef/core/saving/transactions
merry93

2022/10/03 02:34

お返事ありがとうございます。 ①②③のような複数の更新(Insert、Delete、Update等、更新対象テーブルも複数あり)の中で重大なエラーはロールバックしてプログラムを終了、一時的なエラーはリトライ(最大リトライ回数を超えたらロールバックして終了)したいです。
退会済みユーザー

退会済みユーザー

2022/10/03 03:55

あなたの言う「重大」と「一時的」はどうやって判断できるのですか?
退会済みユーザー

退会済みユーザー

2022/10/03 03:58

> リトライ(最大リトライ回数を超えたらロールバックして終了)したいです。 何をどのようにリトライするのですか? そもそもリトライというのが無理なような気がしますけど、ホントにリトライできるのでしょうか? 知ってたら教えてください。
merry93

2022/10/03 05:36

ご指摘ありがとうございます。 一時的というのは ■「SQL Database と SQL Managed Instance での一時的な接続エラーのトラブルシューティング」 のEntLib60 IsTransient メソッドのソース コード https://learn.microsoft.com/ja-jp/azure/azure-sql/database/troubleshoot-common-connectivity-issues?view=azuresql にあるような case 10928: case 10929: case 10053: case 10054: case 10060: case 40197: case 40540: case 40613: case 40143: case 233: case 64: 辺りのエラーコードを指します。 ご案内いただいた ■「チュートリアル: ASP.NET MVC アプリで Entity Framework で接続の回復性とコマンド インターセプトを使用する」 にも少し記載があります。 ↓ Student ページを実行し、検索文字列として「スロー」と入力すると、このコードは、エラー番号 20 のダミー SQL Database例外を作成します。これは、通常は一時的であると認識される型です。 現在一時的と認識されているその他のエラー番号は、64、233、10053、10054、10060、10928、10929、40197、40501、および 40613 ですが、これらは新しいバージョンのSQL Databaseで変更される可能性があります。
退会済みユーザー

退会済みユーザー

2022/10/03 05:56

なるほど。 でも、そこまで調べがついているのならなぜ質問してきたのか解せません。
merry93

2022/10/03 08:50

Entity Frameworkが不勉強で意味の分からないところがありまして質問させていただきました。 ご案内いただいたページのサンプルを実際に動かしてみて挙動を把握することができました。 当方の稚拙な質問に丁寧にご対応いただきまして本当にありがとうございました。
guest

0

回答いただいたページと、
Entity Framework 6 で Azure の SQL データベースにアクセスするとセマフォがうんたら言われる問題への対処
https://qiita.com/keromichan16/items/d52d96f24cea017a5d05
で見通しが立ちました。
要は、
ShouldRetryOn
内にリトライしたいエラーをキャッチするだけでした。
ちなみに、当方が参考したページとは違います(再検索するもみつかりません)が、
Azure SQL DBでEntity Framework
https://qiita.com/karkn/items/76ef77074fea0eb36950
の一番下の、トランザクション全体がリトライ対象というコードと組み合わせても動作しませんでした。

投稿2022/10/03 08:58

merry93

総合スコア17

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.53%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問