Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C语言中的嵌套数据库事务#_C#_Database - Fatal编程技术网

C# C语言中的嵌套数据库事务#

C# C语言中的嵌套数据库事务#,c#,database,C#,Database,我有一个基类,它声明了对数据库处理程序实例(DBH)的私有非静态引用 DBH是一个用于简化派生类的数据库操作的类。它包含常用的方法,如ExecuteScalar,StartTransaction等;它在应用程序环境中提供了额外的好处,如缓存和zero配置 派生类的实例使用DBH在数据库中读取/保存其状态,因为它们的操作不是原子的,所以所有派生类都使用此事务。一切都在一个地方进行:在基类中声明了一个名为InsertUpdate()的虚拟方法 接下来,我有一个派生类实例的集合(称为Book)。我想将

我有一个基类,它声明了对
数据库处理程序
实例(DBH)的私有非静态引用

DBH是一个用于简化派生类的数据库操作的类。它包含常用的方法,如
ExecuteScalar
StartTransaction
等;它在应用程序环境中提供了额外的好处,如缓存和
zero配置

派生类的实例使用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);
DatabaseHandler dbh=newdatabasehandler()
t=dbh.StartTrasaction();
foreach(在Book中键入o)
{
o、 prop1=。。
o、 prop2=。。。
o、 方法1()。。。
o、 InsertUpdate(t);//使用自己的DatabaseHandler实例并启动自己的事务
}
胸径.尾数(t);
目前,
InsertUpdate
方法没有参数。我想我必须引入一个重载版本,它接受一个事务对象


除了解决我目前的问题,还有什么设计问题我需要知道吗?如何改进此设计或建立更好的设计?

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

您看过名称空间了吗?除非您出于某种原因已经打折,否则您可能能够利用此处提供的内置嵌套事务支持-例如:

  using (var scope = new TransactionScope())
  {
    // call a method here that uses a nested transaction
    someObject.SomeMethodThatAlsoUsesATransactionScope();

    scope.Complete();
  }
确保你

就我个人而言,我通常会实现一个类似TrasactionScope的对象,将数据加载到TLS上,这样做的另一个好处是有一个工厂,可以方便地进行分析和日志记录


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

问题是对象使用SqlConnection.BeginTransaction我不确定TransactionScope是否可以与之混合。SqlConnection.BeginTransaction和TransactionScope不能安全混合。我同意使用System.Transactions是最好的。TransactionScope非常易于使用。如果您想对登记有更多的控制权,可以改用CommitteableTransaction和SqlConnection.EnglistTransaction。