代码之家  ›  专栏  ›  技术社区  ›  majkinetor

C中的嵌套数据库事务#

  •  2
  • majkinetor  · 技术社区  · 15 年前

    我有一个基类声明了对 DataBase Handler 实例(DH)。

    dbh是一个用来简化派生类的数据库操作的类。它包含了通常的方法,比如 ExecuteScalar , StartTransaction 此外,它在应用程序上下文中提供了额外的好处,如缓存和 zero configuration .

    派生类的实例使用dbh在数据库中读取/保存其状态,由于它们的操作不是原子的,所以所有派生类都使用此事务。一切都在一个地方进行:一个虚拟方法 InsertUpdate() 在基类中声明。

    接下来,我有一个派生类实例的集合(称为book)。我想将收集更新作为事务处理。

    我想实现类似的目标:

    DatabaseHandler dbh = new DatabaseHandler()
    
    t = dbh.StartTrasaction();
    foreach( Type o in Book<Type> ) 
    {
        o.prop1 = ..
        o.prop2 = ...
        o.method1() ...
    
        o.InsertUpdate(t);  // uses its own instance of DatabaseHandler and starts its own transaction
    }
    dbh.EndTransaction(t);
    

    目前 InsertUpdate 方法是无参数的。我想我必须引入一个接受事务对象的重载版本。

    除了解决我目前的问题,还有什么设计问题需要我了解吗?我怎样才能改进这个设计或建立一个更好的设计?

    3 回复  |  直到 15 年前
        1
  •  2
  •   Community dbr    7 年前

    确定你 read this question

    就我个人而言,我通常 "my own" 一个TrasactionScope类对象的实现,该对象将数据古怪地放到TLS上,另外还有一个好处,那就是拥有一个允许轻松分析和记录的工厂。

    对我来说,你目前的设计听起来相当复杂。通过将原始数据库访问代码与类分离,它将减少重复(并避免要求所有数据访问类从基类继承)。与数据库访问的一组静态方法相反,定义一个对象将简化测试(您可以替换一个模拟类)。

        2
  •  2
  •   Steve Willcock    15 年前

    你看过吗 System.Transactions 命名空间?除非您出于某种原因已经贴现,否则您可能能够利用内置的嵌套事务支持,例如:

      using (var scope = new TransactionScope())
      {
        // call a method here that uses a nested transaction
        someObject.SomeMethodThatAlsoUsesATransactionScope();
    
        scope.Complete();
      }
    
        3
  •  0
  •   cjk    15 年前

    如果更新都发生在同一个数据库connectino上,那么嵌套事务将按预期工作。每个insertupdate()将运行自己的事务,dbh上的整个事务能够回滚整个事务。