2018/03/22

[.NET Core]Entity Framework CoreのDbContext#SaveChangesがトランザクション処理をしていることを確認する


はじめに

前の記事では、SELECT 処理の SQL ログの出力方法をご紹介しましたが、更新系のログをフィルタをかけない状態のものをご紹介していませんでした。

なぜフィルタをかけない更新系のログを見る必要があるかというと、DbContext#SaveChanges メソッドを呼び出すだけでトランザクション処理を行っていることを確認するためです。

DbContext#SaveChanges メソッドを呼び出して例外処理をするだけで、簡単にトランザクション処理を行うことができるということですね。

では、実際に更新系の SQL ログを確認してみましょう。

SQL ログフィルタの解除

前の記事のデータベースコンテキストクラスの以下の部分を変更します。これで SQL ログがフィルタされなくなります。

   public static readonly LoggerFactory MyLoggerFactory
        = new LoggerFactory(new[]
        {
            new ConsoleLoggerProvider((_, __) => true, true) //(変更)
        });

 

更新処理を記述

Program.cs の Main メソッドを以下のように、新規追加の更新系処理に変更します。 

    static void Main(string[] args)
    {
        using (var db = new consoletestContext())
        {
            db.Book.Add(new Book{Title="おはよう", Price=1000});
            db.Book.Add(new Book{Title="こんにちは", Price=500});
            db.Book.Add(new Book{Title="こんばんは", Price=800});
            db.SaveChanges();
        }
    }

 

SQLログの確認

では、実際のプログラムを実行して SQL ログを確認してみましょう。

$ dotnet run
dbug: Microsoft.EntityFrameworkCore.Infrastructure[10401]
      An 'IServiceProvider' was created for internal use by Entity Framework.
info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
      Entity Framework Core 2.0.1-rtm-125 initialized 'consoletestContext' using provider 'Npgsql.EntityFrameworkCore.PostgreSQL' with options: None
dbug: Microsoft.EntityFrameworkCore.Database.Connection[20000]
      Opening connection to database 'consoletest' on server 'tcp://localhost:5432'.
dbug: Microsoft.EntityFrameworkCore.Database.Connection[20001]
      Opened connection to database 'consoletest' on server 'tcp://localhost:5432'.
dbug: Microsoft.EntityFrameworkCore.Database.Transaction[20200]
      Beginning transaction with isolation level 'ReadCommitted'.
dbug: Microsoft.EntityFrameworkCore.Database.Command[20100]
      Executing DbCommand [Parameters=[@p0='?', @p1='?', @p2='?', @p3='?', @p4='?', @p5='?'], CommandType='Text', CommandTimeout='30']
      INSERT INTO "book" ("price", "title")
      VALUES (@p0, @p1)
      RETURNING "id";
      INSERT INTO "book" ("price", "title")
      VALUES (@p2, @p3)
      RETURNING "id";
      INSERT INTO "book" ("price", "title")
      VALUES (@p4, @p5)
      RETURNING "id";
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
      Executed DbCommand (59ms) [Parameters=[@p0='?', @p1='?', @p2='?', @p3='?', @p4='?', @p5='?'], CommandType='Text', CommandTimeout='30']
      INSERT INTO "book" ("price", "title")
      VALUES (@p0, @p1)
      RETURNING "id";
      INSERT INTO "book" ("price", "title")
      VALUES (@p2, @p3)
      RETURNING "id";
      INSERT INTO "book" ("price", "title")
      VALUES (@p4, @p5)
      RETURNING "id";
dbug: Microsoft.EntityFrameworkCore.Database.Command[20300]
      A data reader was disposed.
dbug: Microsoft.EntityFrameworkCore.Database.Transaction[20202]
      Committing transaction.
dbug: Microsoft.EntityFrameworkCore.Database.Connection[20002]
      Closing connection to database 'consoletest' on server 'tcp://localhost:5432'.
dbug: Microsoft.EntityFrameworkCore.Database.Connection[20003]
      Closed connection to database 'consoletest' on server 'tcp://localhost:5432'.
dbug: Microsoft.EntityFrameworkCore.Database.Transaction[20204]
      Disposing transaction.

 

色付けできないので分かりづらいかもしれませんが、10〜11行目の部分でトランザクションが開始されていることが分かります。

下から7〜8行目でコミットしていることも分かりますね。

これで、DbContext#SaveChanges メソッドを呼び出せば自動でトランザクション処理をしていることが分かりました。

このログでもう1つ着目したいのが、INSERT 文が全てパラメータ化されており、SQL インジェクションの脆弱性が発生しないようになっていることです。

Entity Framework Core を使用するだけで SQL インジェクション対策になる訳ですね。

Entity Framework Core は LINQ が使えることで生産性が高いことが有名ですが、セキュリティ的にもオススメです。

 

おわりに

DbContext#SaveChanges メソッドがトランザクション処理を行うことが確認できましたが、いかがだったでしょうか。

ログを確認しないと分からないのが難点ではありますが、実際にログを確認したので安心して使用することができますね。 


スポンサーリンク


このエントリーをはてなブックマークに追加




Twitter ではブログにはない、いろんな情報を発信しています。


コメント

コメントを書く



プロフィール

  • 名前:fnya
    経歴:
    SE としての経験は15年以上。様々な言語と環境で業務系システム開発を行い、セキュリティ対策などもしていました。なんちゃってSE。

    フリーウェア、Webサービス開発のためにEntyで支援を受け付けています。ご支援のほどよろしくお願いいたします。

    Twitter では、ブログでは取り上げない情報も公開しています。


    ブログについて

    このブログは、IT、スマートフォン、タブレット、システム開発などに関するさまざまな話題を取り上げたり、雑感などをつづっています。


    >>自作ツール
    >>運営サイト
    >>Windows 10 まとめ
    >>ブログ詳細

    Twitter のフォローはこちらから Facebook ページはこちら Google+ページはこちら RSSフィードのご登録はこちらから


最近の記事