我想创建一个C#应用程序,在其中复制两个不同文件夹(已包含旧版本文件)中的一些文件并运行SQL脚本。在整个过程中,如果产生任何异常,我需要回滚所有更改。如何实现回滚功能?
对于sql脚本,可以使用转换,但是如何使用回滚实现文件复制过程?
我想创建一个C#应用程序,在其中复制两个不同文件夹(已包含旧版本文件)中的一些文件并运行SQL脚本。在整个过程中,如果产生任何异常,我需要回滚所有更改。如何实现回滚功能?
对于sql脚本,可以使用转换,但是如何使用回滚实现文件复制过程?
在替换之前,您可以从旧文件复制一份,然后如果发生异常,则从此复制恢复。
它适合您的使用情况将文件复制到临时目录,然后将整个目录移动到位?如果是这样,回滚就像删除临时目录一样简单。
如果该目录的移动操作失败,你会怎么做?这几乎不是原子操作,所以它*可能*失败。 – Joey 2009-11-12 07:58:25
此举实际上是大多数操作系统中的重命名。它发生在一个单一的操作。操作系统在更改期间锁定表示目录的文件,以便它像原子一样工作。查看Linux'mv'命令的这个古代手册中提供的保证:http://www.linuxmanpages.com/man2/rename.2.php – 2009-11-12 10:17:46
如果可能,您可以利用Transactional NTFS。如果没有,那么你可以保留你所做的操作列表,并在需要回滚时做相反的操作。
或者您可以发展为软件开发人员并使用Command Pattern并实现BatchCommand。通过命令可以非常容易地添加撤消功能并以智能方式进行封装。然后BatchCommand可以在其列表中的每个Command上调用undo()。
对于一个好的底漆模式,看看Head First Design Patterns
我会复制到新的文件追加后缀和一个随机数,从而避免与已经存在的文件名冲突。
示例... 旧文件=“myfile.txt”,新文件=“myfile.txt.new.285387”。
然后,当复制过程完成后,我会... - 将旧文件的名称标记为“myfile.txt.old.3464353”。 - 将新文件命名为“myfile.txt” - 最后将删除旧的文件。
试试这个代码
public bool updateusertable(string UserName,string Password,string Datetime)
{
bool bResult = false;
SqlTransaction tx;
try
{
tx=conn.Begintransaction();
SqlCommand Ocmd = new SqlCommand();
Sqlconnect = Cconnect.OpenSqlConnection();
Ocmd.Connection = Sqlconnect;
Ocmd.CommandType = CommandType.StoredProcedure;
Ocmd.CommandText = "SP_User_login_Update";
Ocmd.Parameters.Add("@UserName", SqlDbType.VarChar, 100).Value = UserName;
Ocmd.Parameters.Add("@Password", SqlDbType.VarChar, 100).Value = Password;
Ocmd.Parameters.Add("@lastlogin", SqlDbType.VarChar, 100).Value = Datetime;
int i = Ocmd.ExecuteNonQuery();
if (i <= 1)
{
bResult = true;
tx.Commit();
}else
{
tx.Rollback();
}
}
catch (Exception ex)
{
string msg = ex.Message.ToString();
tx.Rollback();
}
finally
{
}
return bResult;
}
根据您指定的系统上,文件系统的变化也可以放在一个事务。从Windows Vista开始,NTFS具有此功能。 – Joey 2009-11-12 07:47:38