我有一个场景,其中我必须处理多个.sQL文件,每个文件包含3-4个插入或更新查询,现在当一个文件中的任何查询失败时,我做rollback整个事务意味着我们回滚整个文件,并且在该文件提交之前执行的所有其他文件,我想要一个选项,其中用户可以rollback整个事务意味着在一个文件中执行的所有查询和包含错误的特定文件之前执行的所有文件,如果用户想跳过包含错误的特定文件,我们将只rollback包含错误的单个文件,所有其他文件将被提交,我现在正在使用SQL事务。没有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()
}发布于 2015-01-20 13:52:01
您似乎正在寻找SavePoints,即部分回滚然后恢复更大事务的选项。AFAIK TransactionScope doesn't support SavePoints,因此您需要直接与本地提供程序打交道(例如,如果您的关系型数据库是Sql Server,则为SqlClient )。(例如,您不能利用TransactionScope的能力来实现DTC的SavePoints等效物,例如跨分布式数据库、不同的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)
)发布于 2016-01-12 16:52:18
将所有insert、update查询保留在try{..}catch(..){..}中,如果发生任何异常,则在catch回滚中回滚数据库事务。
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();
}
}
}https://stackoverflow.com/questions/28038489
复制相似问题