看来您正在寻找SavePoints,即部分回滚然后恢复更大事务的选项。AFAIKTransactionScope
不支持 SavePoints,因此您需要直接与本地提供者打交道(例如SqlClient
,如果您的 RDBMS 是 Sql Server)。(即,您不能利用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)
)