C# 所以TransactionScope仅在处理数据库时使用
我通过在范围内复制一个文件进行测试,然后抛出错误,认为它会恢复重命名。它没有恢复:( 发件人:C# 所以TransactionScope仅在处理数据库时使用,c#,C#,我通过在范围内复制一个文件进行测试,然后抛出错误,认为它会恢复重命名。它没有恢复:( 发件人: System.Transactions基础架构使事务 通过支持 在SQL Server、ADO.NET、MSMQ和 Microsoft分布式事务协调器(MSDTC)。 因此,您不能对文件系统使用System.Transactions 有组件,但Microsoft强烈建议开发人员利用其他方法来满足您的应用程序需求 你也可以看看 或者您需要实现IEnlistmentNotification,并允许手动标准
System.Transactions
基础架构使事务
通过支持
在SQL Server、ADO.NET、MSMQ和
Microsoft分布式事务协调器(MSDTC)。
因此,您不能对文件系统使用System.Transactions
有组件,但Microsoft强烈建议开发人员利用其他方法来满足您的应用程序需求
你也可以看看
或者您需要实现
IEnlistmentNotification
,并允许手动标准文件操作使用TransactionScope
。例如,要对现有文件启用写操作回滚,它首先创建要写入的文件备份,然后写入备份文件,最后替换中的如果事务已提交,则使用备份/修改的文件初始化文件;如果事务已回滚,则删除备份文件;如果文件系统不支持事务,则删除备份文件。然后,您可以删除catch块中复制的文件。线程中已存在大量良好信息,这些信息是正确的;尤其是@Roman Marusyk。我想到了什么,并给出了一个利用System.Transactions
和Runtime.InteropServices
名称空间的小例子。主要功能是movefiletransacticedw
,您可以找到更多关于它的信息
注意:您可以重命名名称空间,用于测试
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Transactions;
namespace MoveFileRollback
{
public abstract class FileTransactionHelper
{
[DllImport("Kernel32.dll")]
private static extern bool CloseHandle(IntPtr handle);
[DllImport("Kernel32.dll")]
private static extern bool MoveFileTransactedW([MarshalAs(UnmanagedType.LPWStr)]string existingfile, [MarshalAs(UnmanagedType.LPWStr)]string newfile,
IntPtr progress, IntPtr lpData, IntPtr flags, IntPtr transaction);
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("79427A2B-F895-40e0-BE79-B57DC82ED231")]
private interface IKernelTransaction
{
void GetHandle([Out] out IntPtr handle);
}
public static bool MoveFile(string existingFile, string newFile)
{
bool success = true;
using (TransactionScope tx = new TransactionScope())
{
if (Transaction.Current != null)
{
IKernelTransaction kt = (IKernelTransaction)TransactionInterop.GetDtcTransaction(Transaction.Current);
IntPtr txh;
kt.GetHandle(out txh);
if (txh == IntPtr.Zero) { success = false; return success; }
success = MoveFileTransactedW(existingFile, newFile, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, txh);
if (success)
{
tx.Complete();
}
CloseHandle(txh);
}
else
{
try
{
File.Move(existingFile, newFile);
return success;
}
catch (Exception ex) { success = false; }
}
return success;
}
}
}
}
快速实施
if (FileTransactionHelper.MoveFile(@"C:\file1.txt", @"C:\file1.txt.backup1")){
MessageBox.Show("MOVED");
}
我在几个不同的文件上对此进行了测试,包括在MoveFile
中抛出异常,当抛出异常时,事务不会被标记为Complete
,移动也不会发生
如果您有问题,请告诉我,我希望这可能会有点有用。没错。事务通常是数据库的一部分,但也可以扩展到类似的介质,如消息队列:我不知道有任何文件系统支持事务。文档中的内容可能会重复,尤其是文档中的内容会使您变瘦k TransactionScope是否适用于文件系统?
if (FileTransactionHelper.MoveFile(@"C:\file1.txt", @"C:\file1.txt.backup1")){
MessageBox.Show("MOVED");
}