MySql.Data.EntityFrameworkの挙動を詳しく知りたかったので、試してみた挙動をまとめました
前提知識
- MySql.Data.EntityFrameworkの基本
- MySQLに関する基本知識および用語
- 非同期処理の話
この辺りは知っているものとして取り扱いはしません。
トランザクションの方法
DbContext db = new AuthenticationDbContext();
db.Database.BeginTransaction();
// この間にクエリを投げる
db.Database.Commit();
MySql.Data.EntityFrameworkのコネクションの取り扱い
DbContextのインスタンス
基本的にはDbContextインスタンスを用いて、データベースに対してアクセスを行うのですが、
少し知識のある方だとコネクションのプーリングがどうなっているのか気になるところだと思うので試してみました。
検証1:コネクションはプーリングされているのか?
// ここではコネクションは確保されていない
var db = new AuthenticationDbContext();
// ここでもコネクションは確保されていない
var db2 = new AuthenticationDbContext();
// ここで初めてひとつ確保される
var transaction = db.Database.BeginTransaction();
db.Users.Add(new Database.Authentication.Table.User { Id = Guid.NewGuid().ToString() });
db.SaveChanges();
// コミットが終わってもコネクションはひとつ確保されたまま
transaction.Commit();
// インスタンスは別だがコネクションはひとつのまま
var transaction2 = db2.Database.BeginTransaction();
db2.Users.Add(new Database.Authentication.Table.User { Id = Guid.NewGuid().ToString() });
db2.SaveChanges();
transaction2.Commit();
どうやらされている模様
検証2:二つのコネクションが必要そうなことをするとどうなるか?
// ここではコネクションは確保されていない
var db = new AuthenticationDbContext();
// ここでもコネクションは確保されていない
var db2 = new AuthenticationDbContext();
// ここで初めてひとつ確保される
var transaction = db.Database.BeginTransaction();
db.Users.Add(new Database.Authentication.Table.User { Id = Guid.NewGuid().ToString() });
// 一つ目のトランザクションが完了していないので二つ目が確保される
var transaction2 = db2.Database.BeginTransaction();
db2.Users.Add(new Database.Authentication.Table.User { Id = Guid.NewGuid().ToString() });
db.SaveChanges();
transaction.Commit();
db2.SaveChanges();
transaction2.Commit();
必要だったら確保するみたいですね。かしこい。
検証3:どこまでコネクション確保されるのか
検証結果は100個を超えるタイミングでスレッドがロックされたので上限があるみたい。(MySql側のMaxConnectionsに引っかかってるわけではなさそう)
とここまで調べてConnectionStringsに記述できることが分かった。当たり前か。
https://msdn.microsoft.com/ja-jp/library/system.data.sqlclient.sqlconnection.connectionstring(v=vs.110).aspx