繁体   English   中英

子女父母交易回滚

[英]Child Parent Transactions roll back

我有一个场景,我必须处理多个.sQL文件,每个文件包含3-4个插入或更新查询,现在当文件中的任何查询失败时,我会rollback整个事务,这意味着整个文件都将被回滚,而所有其他在提交该文件之前执行的文件,我想要一个选项,使用户可以rollback整个事务,这意味着将执行一个文件中的所有查询,以及在包含错误的特定文件之前执行的所有文件,如果用户希望跳过该特定文件而出现错误,我们将只是rollback单个文件,其中包含错误,所有其他文件都会被提交,我现在正在使用SQL Transaction,没有TransactionScope但是显然,如果需要并且可能的话,我也可以切换TransactionScope() ,目前我的代码是伪的(我想要的)是如下

Var Files[]
for each (string query in Files)
{
  Execute(Query)
IF(TRUE)
CommitQuery()
Else
result=MBOX("IF You want to abort all files or skip this one")
if(result=abort)
rollbackall()
else
QueryRollBack()
}

看来您正在寻找SavePoints ,即部分回滚然后继续进行较大事务的选项。 AFAIK TransactionScope 不支持SavePoints,因此您需要直接处理本机提供程序(例如,如果您的RDBMS是Sql Server,则为SqlClient )。 (即,您不能利用TransactionScope来实现与SavePoints等效的DTC ,例如,在分布式数据库,不同的RDBMS或并行事务中)

就是说,我会建议用户在事务处理开始之前选择跳过或中止的策略,因为等待UI响应的代价很高,而大量行仍被锁定-这很可能会引起争用问题。

编辑

这是使用SavePoints的一个小示例。 插入Foo1和Foo3,Foo2回滚到先前的保存点。

using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["Foo"].ConnectionString))
{
    conn.Open();
    using (var txn = conn.BeginTransaction("Outer"))
    {
        txn.Save("BeforeFoo1");
        InsertFoo(txn, "Foo1");

        txn.Save("BeforeFoo2");
        InsertFoo(txn, "Foo2");
        txn.Rollback("BeforeFoo2");

        txn.Save("BeforeFoo3");
        InsertFoo(txn, "Foo3");
        txn.Commit();
    }
}

InsertFoo在哪里:

private void InsertFoo(SqlTransaction txn, string fooName)
{
    using (var cmd = txn.Connection.CreateCommand())
    {
        cmd.Transaction = txn;
        cmd.CommandType = CommandType.Text;
        cmd.CommandText = "INSERT INTO FOO(Name) VALUES(@Name)";
        cmd.Parameters.Add(new SqlParameter("@Name", SqlDbType.VarChar)).Value = fooName;
        cmd.ExecuteNonQuery();
    }
}

基础表是:

create table Foo
(
    FooId INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
    Name NVARCHAR(50)
)

将所有插入,更新查询保留在try{..}catch(..){..} ,如果发生任何异常,请在catch中回滚db事务。

     private void InsertFoo(SqlTransaction txn, string fooName)
     {
         using (var cmd = txn.Connection.CreateCommand())
         {
             try
             {
                 do your process here...
                 cmd.Commit();
             }
             catch(Exception ex)
             {
                cmd.Rollback();
             }
         }
     }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM