这不是一个完整的答案,但我怀疑这样的事情可能会走上正确的道路。我的问题是我不完全确定如何在 TransactionScope 中获取 SqlTransaction。
/// <summary>
/// Makes a code block transactional in a way that can be partially rolled-back. This class cannot be inherited.
/// </summary>
/// <remarks>
/// This class makes use of SQL Server's SAVEPOINT feature, and requires an existing transaction.
/// If using TransactionScope, utilize the DependentTransaction class to obtain the current Transaction that this class requires.
/// </remarks>
public sealed class TransactionSavePoint : IDisposable
{
public bool IsComplete { get; protected set; }
internal SqlTransaction Transaction { get; set; }
internal string SavePointName { get; set; }
private readonly List<ConnectionState> _validConnectionStates = new List<ConnectionState>
{
ConnectionState.Open
};
public TransactionSavePoint(SqlTransaction transaction, string savePointName)
{
IsComplete = false;
Transaction = transaction;
SavePointName = savePointName;
if (!_validConnectionStates.Contains(Transaction.Connection.State))
{
throw new ApplicationException("Invalid connection state: " + Transaction.Connection.State);
}
Transaction.Save(SavePointName);
}
/// <summary>
/// Indicates that all operations within the savepoint are completed successfully.
/// </summary>
public void Complete()
{
IsComplete = true;
}
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
if (!IsComplete)
{
Transaction.Rollback(SavePointName);
}
}
}
这将像这样被消耗,与 TransactionScope 非常相似:
SqlTransaction myTransaction = Foo();
using (var tsp = new TransactionSavePoint(myTransaction , "SavePointName"))
{
try
{
DoStuff();
tsp.Complete
}
catch (Exception err)
{
LogError(err);
}
}