我希望有一个复制文件然后在数据库中插入记录的事务。 像下面的语句,但事务不包括复制文件。 解决方案是什么?
using (TransactionScope scope1 = new TransactionScope())
{
// Copy a file
fileMgr.Move(srcFileName, destFileName);
// Insert a database record
dbMgr.ExecuteNonQuery(insertSql);
scope1.Complete();
}
答案 0 :(得分:16)
尝试使用.NET Transactional File Manager
此库允许您在以下事务中包装文件系统操作:
// Wrap a file copy and a database insert in the same transaction
TxFileManager fileMgr = new TxFileManager();
using (TransactionScope scope1 = new TransactionScope())
{
// Copy a file
fileMgr.Copy(srcFileName, destFileName);
// Insert a database record
dbMgr.ExecuteNonQuery(insertSql);
scope1.Complete();
}
答案 1 :(得分:5)
较新版本的Windows具有可以使用的称为TxF(事务性NTFS)的东西。这里有一个代码示例:WINDOWS VISTA - INTRODUCING TXF IN C# (PART 2) - USING SYSTEM.TRANSACTIONS AND THE DTC(我很抱歉大写锁定,但页面标题是:-))
您必须使用MoveFileTransacted代替DeleteFileTransactioned
。一旦你进入DTC,你的SQL连接应该注册到它,所以一切都应该是一个大的交易。
答案 2 :(得分:0)
在使用transactional NTFS
或任何其他建议之前,请先阅读本文:https://docs.microsoft.com/nl-nl/windows/desktop/FileIO/deprecation-of-txf
TxF是一组复杂且细微的API,第三方应用程序通常不使用。由于这些API在将来的Windows版本中可能不可用,并且存在实现TxF开发所针对的许多方案的更简单的替代方法,Microsoft强烈建议开发人员研究这些替代方法,而不是创建一个替代方法。在他们的应用程序中依赖TxF。
实现ACID
的更好方法是使用Filestream storage
答案 3 :(得分:-1)
您可以手动滚动自己的文件事务,如果提交失败,请将文件移回原来的位置
using (TransactionScope scope1 = new TransactionScope())
{
// Copy a file
fileMgr.Move(srcFileName, destFileName);
try
{
// Insert a database record
dbMgr.ExecuteNonQuery(insertSql);
scope1.Complete();
} catch (Exception) {
fileMgr.Move(destFileName, srcFileName);
}
}
我不是100%用于确定是否发生错误提交事务的语法,但我认为这说明了这个概念