您需要使用新的 TxF,即在 Vista、Windows 7 和 Windows Server 2008 中引入的 Transacted NTFS。这是一篇很好的介绍性文章:Enhance Your Apps With File System Transactions。它包含一个将文件操作注册到系统事务中的小型托管示例:
// IKernelTransaction COM Interface
[Guid("79427A2B-F895-40e0-BE79-B57DC82ED231")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IKernelTransaction
{
int GetHandle(out IntPtr pHandle);
}
[DllImport(KERNEL32,
EntryPoint = "CreateFileTransacted",
CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern SafeFileHandle CreateFileTransacted(
[In] string lpFileName,
[In] NativeMethods.FileAccess dwDesiredAccess,
[In] NativeMethods.FileShare dwShareMode,
[In] IntPtr lpSecurityAttributes,
[In] NativeMethods.FileMode dwCreationDisposition,
[In] int dwFlagsAndAttributes,
[In] IntPtr hTemplateFile,
[In] KtmTransactionHandle hTransaction,
[In] IntPtr pusMiniVersion,
[In] IntPtr pExtendedParameter);
....
using (TransactionScope scope = new TransactionScope())
{
// Grab Kernel level transaction handle
IDtcTransaction dtcTransaction =
TransactionInterop.GetDtcTransaction(managedTransaction);
IKernelTransaction ktmInterface = (IKernelTransaction)dtcTransaction;
IntPtr ktmTxHandle;
ktmInterface.GetHandle(out ktmTxHandle);
// Grab transacted file handle
SafeFileHandle hFile = NativeMethods.CreateFileTransacted(
path, internalAccess, internalShare, IntPtr.Zero,
internalMode, 0, IntPtr.Zero, ktmTxHandle,
IntPtr.Zero, IntPtr.Zero);
... // Work with file (e.g. passing hFile to StreamWriter constructor)
// Close handles
}
您需要在同一个事务中注册您的 SQL 操作,这将在 TransactionScope 下自动发生。但我强烈建议您覆盖默认的 TransactionScope options 以使用 ReadCommitted 隔离级别:
using (TransactionScope scope = new TransactionScope(
TransactionScope.Required,
new TransactionOptions
{ IsolationLevel = IsolationLEvel.ReadCommitted}))
{
...
}
如果不这样做,您将获得默认的 Serializable 隔离级别,这在大多数情况下过于矫枉过正。