前提・実現したいこと
・ビジネスロジック層でトランザクションを制御したい。
・データベースアクセス層に、ビジネスロジック層からDbContextやTransactionを引数で渡すようなことはしたくない。
作ってみた設計
1.ビジネスロジック層で使用するためのscopeを作った。
C#
1 public class CustomDbContextScope : IDisposable 2 { 3 [ThreadStatic] 4 private static OurDbContext _dbContext; 5 6 [ThreadStatic] 7 private static DbContextTransaction _transaction; 8 9 internal static OurDbContext DbContext { get { return _dbContext; } } 10 internal static DbContextTransaction Transaction { get { return _transaction; } } 11 12 private bool isComplete = false; 13 14 public CustomDbContextScope() 15 { 16 if (_dbContext != null || _transaction != null) 17 { 18 throw new Exception("CustomDbContextScopeのコンストラクタで既にコネクションかトランザクションがある"); 19 } 20 _dbContext = new OurDbContext(); 21 _transaction = _dbContext.Database.BeginTransaction(); 22 } 23 24 public void Complete() 25 { 26 this.isComplete = true; 27 } 28 29 public void Dispose() 30 { 31 if (this.isComplete) 32 { 33 _transaction.Commit(); 34 _dbContext.Dispose(); 35 _transaction = null; 36 _dbContext = null; 37 } 38 else 39 { 40 _transaction.Rollback(); 41 _dbContext.Dispose(); 42 _transaction = null; 43 _dbContext = null; 44 } 45 } 46 }
2.データベースアクセス層で使用するためのscopeを作った。
C#
1 public class CustomContextUserScope : IDisposable 2 { 3 private OurDbContext _dbContext; 4 private bool isInTransaction = false; 5 6 public CustomContextUserScope () 7 { 8 if (CustomDbContextScope.DbContext == null) 9 { 10 this._dbContext = new OurDbContext(); 11 } 12 else 13 { 14 this._dbContext = CustomDbContextScope.DbContext; 15 this.isInTransaction = true; 16 } 17 } 18 19 public OurDbContext DbContext { get { return _dbContext; } } 20 21 public void Dispose() 22 { 23 if (!this.isInTransaction) 24 { 25 this._dbContext.Dispose(); 26 } 27 } 28 }
3.ビジネスロジック層での使用方法
C#
1using( CustomDbContextScope scope = new CustomDbContextScope() ) 2{ 3 // データベースアクセス層の呼び出しなど 4}
4.データベースアクセス層での使用方法
C#
1using( CustomDbContextUserScope scope = new CustomDbContextUserScope() ) 2{ 3 OurDbContext dbContext = scope.DbContext; 4 // dbContextを使った処理 5}
聞きたいこと
1.ThreadStatic属性やDbContext.Dispose()の仕組みがよくわかってないのですが、以上の設計は安全でしょうか。
2.あまりしっくりいってないのですが、以上の設計よりもよい設計がないでしょうか
回答2件
あなたの回答
tips
プレビュー