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");
            }