首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >子父事务回滚

子父事务回滚
EN

Stack Overflow用户
提问于 2015-01-20 13:41:58
回答 2查看 1.1K关注 0票数 1

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

代码语言:javascript
复制
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()
}
EN

回答 2

Stack Overflow用户

发布于 2015-01-20 13:52:01

您似乎正在寻找SavePoints,即部分回滚然后恢复更大事务的选项。AFAIK TransactionScope doesn't support SavePoints,因此您需要直接与本地提供程序打交道(例如,如果您的关系型数据库是Sql Server,则为SqlClient )。(例如,您不能利用TransactionScope的能力来实现DTCSavePoints等效物,例如跨分布式数据库、不同的RDBMS或并行事务)

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

编辑

下面是一个使用SavePoints的小示例。插入Foo1和Foo3后,Foo2将回滚到上一个保存点。

代码语言:javascript
复制
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是:

代码语言:javascript
复制
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();
    }
}

底层的表是:

代码语言:javascript
复制
create table Foo
(
    FooId INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
    Name NVARCHAR(50)
)
票数 1
EN

Stack Overflow用户

发布于 2016-01-12 16:52:18

将所有insert、update查询保留在try{..}catch(..){..}中,如果发生任何异常,则在catch回滚中回滚数据库事务。

代码语言:javascript
复制
     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();
             }
         }
     }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28038489

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档