[英]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.