如何在后期回滚事务?

时间:2012-10-13 06:09:02

标签: c# asp.net .net sql-server-2008

我有一个数据输入ASP.NET应用程序。在一个完整的数据输入期间,发生许多交易。我想跟踪所有这些事务,以便如果用户想要放弃数据条目,我可以回滚所有保持记录的事务。

SQL 2008,Framework版本是4.0,我使用的是c#。

4 个答案:

答案 0 :(得分:5)

对于不熟悉Web开发的人来说,这总是一个艰难的教训。但这是:

每次往返Web请求都是一个单独的独立执行线程

这意味着,简单地说,每次提交页面请求(单击按钮,导航到新页面,甚至刷新页面),它都可以在与前一个不同的线程上运行。更重要的是,即使您确实两次获得相同的线程,在您的两个请求之间的时间内,线程可能已经处理了其他几个Web请求。

这使得跨多个Web请求跨越简单事务实际上是不可能的。

这是你应该记住的另一个概念:

交易用于批量操作,而非交互式操作。

这意味着事务是短暂的,并且包含顺序(或同时)执行的几个操作,其中所有操作都是原子操作,并且要么全部完成,要么全部失败。事务通常不是设计为长期存在的(意味着等待用户以交互方式决定各种操作)。

网络应用不是桌面应用。它们不像它们那样运作。当你做网络应用程序时,你必须改变你的想法。最重要的经验教训是,每个请求都是一个独立的执行单元。

现在,上面,我说“简单交易”,也称为轻量级或本地交易。还有所谓的分布式事务,使用它们需要分布式事务协调器。 MSDTC非常常用。然而,DT的表现要比LWT慢得多。此外,他们要求将基础设施设置为使用DTC。

可以使用DTC跨Web请求跨越事务。这是通过在分发事务中“登记”,然后以某种方式在请求之间共享此事务标识符来完成的。但是这需要很多工作来设置和处理,并且有很多容易出错的情况。如果您有其他选择,这不是您想要做的事情。

通常,最好将数据添加到临时表或表中,然后在完成最终保存时,将该数据传输到永久表。另一种选择是维护某些状态(例如使用ViewState或Session)来跟踪更改。

一种流行的方法是使用JavaScript在客户端执行操作,然后在完成后将所有更改提交到服务器。但是,如果您需要导航到不同的页面,这很难实现。

答案 1 :(得分:1)

根据您的问题,当用户使用选项将其回滚时,似乎交易已完成。在这种情况下,我怀疑DBMS的事务回滚语义是否可用。所以,我会在应用层提供如下语义:

  1. 可以在数据库上执行的任何原子操作都应封装在Command对象中。每个命令都将实现undo方法,该方法将恢复其execute方法执行的操作。
  2. 每个事务都包含作为其一部分运行的命令列表。该交易将持续存在,以及将来的进一步操作。
  3. 将为用户提供查看可能可能回滚的这些事务的方法。在用户选择交易以将其回滚后,将检索与此类事务对应的命令列表,并在所有这些命令对象上调用撤消方法。
  4. HTH。

答案 2 :(得分:0)

如果您只是在单个保存操作期间管理事务,请使用TransactionScope。但听起来并非如此。

如果用户可能希望放弃n个先前的保存操作,则表明项目可能以草稿形式存在。可能有一个工作草案或许多。随后,必须有一种方法可以隐式或明确地将草案提升为最终版本。想想电子邮件程序如何保存草稿。它实际上并不发送您的消息,您可以随时放弃它,并且您可能会在以后回忆它。当您发送消息时,您已“提交了交易”。

您还可以添加用户界面以回滚到特定版本。

这将是相当多的工作,但如果您愿意保存和管理同一项目的多个副本,则可以完成。

您可以使用状态标志将相同数据的副本保存在同一模式中,以指示它是草稿,或者您可以将数据以中间格式存储在单独的表中。我更喜欢第一种方法,因为它允许使用相同的结构。

答案 3 :(得分:0)

您也可以将它们存储在临时表中,并在稍后阶段将这些记录移动到原始表中。