【问题标题】:Transaction inside of code代码内部的事务
【发布时间】:2012-05-14 06:06:10
【问题描述】:

我遇到了一个问题,我很不确定如何解决这个问题,我想知道为了完成这个任务我应该考虑什么最好的方法。

我们正在开发一个应用程序 VB.net 2.0 和 SQL 2005。允许用户根据可能包含许多已接收商品的购买取消接收。但是,在取消的过程中,会向用户提出一些问题,例如“您要取消 Good #1”。如果是,请删除。然后,“你想取消Good#2”,不,不要删除,然后是另一个问题(如果收到的项目发出,必须由用户手动进行一个过程)。最后,如果所有商品成功取消,我们必须取消接收本身。但是有时候,如果在这个过程中曾经向用户询问过错误或某些情况发生,我们希望取消从一开始所做的任何动作,并使其恢复到原来的状态。所以我想到了Transaction

  1. 我知道有 Transaction for SQL 可以使用,并且我知道如何使用它,但我不能真正使用它,因为用户必须执行可能取消此交易的操作。

  2. 我还记得 .NET 2.X 中的TransactionScope 可以实现类似的功能,我也知道如何使用它。问题来自 TransactionScope 和 MSDTC。使用它时,我们仍然收到错误消息:

分布式事务管理器 (MSDTC) 的网络访问已被禁用。请使用组件服务管理工具在 MSDTC 的安全配置中启用 DTC 以进行网络访问。

我已经尝试过in another stack post 此处描述的内容,效果很好……直到用户重新启动计算机。每次用户重新启动计算机时,他们都必须恢复价值。另外,默认情况下,没有计算机将此值设置为“开”。至少有 10 个计算机基地没有被激活。大约有 300 台计算机安装了这个程序,所以这肯定不是好事情。

所以有人知道我如何实现这一点吗?还有什么可以通过我可以使用的代码进行交易的东西吗?

NOTE1 :我知道有人会说,首先向用户询问条件并在内存中维护值。完成后,如果一切顺利,请使用删除。但是,如果在删除商品 #4 时发生错误怎么办?以及如何为存储过程提供要删除的商品的动态列表?

NOTE2:对不起我的英语,我通常说法语。

NOTE3 :C# 中的任何示例也可以提供,因为我知道 VB 和 C#。

【问题讨论】:

  • 如果你按照 NOTE1 所说的做,嵌入删除到事务中,如果发生错误则回滚。有关批处理内自动回滚的详细信息,请参阅SET XACT_ABORT ON
  • 是的,但我仍然有一个问题,我可能会从接收 #A 中取消 Good #1、3、4、5、8。如何将动态数组传递给存储过程?有办法吗?
  • sql server 中存在 XML 数据类型,因此可以将各种东西作为 XML 参数传递。但我在想你可以自己构建sql语句来响应用户的操作和ExecuteNonQuery这批。
  • 当前操作对每个商品的 2 个单独的表执行 2 次更新,最后执行 2 个存储过程一次,或者如果所有商品都被取消。很难在同一个 ExecuteNonQuery 过程中重新组合它......

标签: sql vb.net winforms transactions


【解决方案1】:

假设您已经有类似的存储过程来管理取消:

create proc CancelGood (@goodID int)
as
   SET NOCOUNT ON
   SET XACT_ABORT ON

   begin transaction

   update table1 set canceled = 1
    where GoodID = @GoodID

   update table2 set on_stock = on_stock + 1
    where GoodID = @GoodID

   commit transaction

如果用户选择'Oui',VB 代码会在canceledGoods 列表中添加一个字符串。我不熟悉 VB.Net;在 c# 中它看起来像:

canceledGoods.Add (string.Format("exec dbo.CancelGood {0}", goodID));

然后,如果cancelledGoods中至少有一个字符串,则构建并执行批处理:

batch = "BEGIN TRANSACTION" +
        " BEGIN TRY " +
        string.Join (Environment.NewLine, canceledGoods.ToArray()) + 
        " END TRY" +
        " BEGIN CATCH " +
        " -- CODE TO CALL IF THERE WAS AN ERROR" +
        "    ROLLBACK TRANSACTION" +
        "    RETURN" +
        " END CATCH" +
        " -- CODE TO CALL AFTER SUCCESSFULL CANCELATION OF ALL GOODS" +
        " COMMIT TRANSACTION"

conn.ExecuteNonQuery (batch);

【讨论】:

  • 这对 C# 来说没问题,在这个项目之前我以前只做 C#,所以我对两者都很熟悉。我会试试你写的东西,稍后再回来。但是,我这边肯定有很多工作,因为我只解释了我的问题的一小部分。我必须尝试回想如何使用这些方法来做到这一点。对我来说可能更容易使用第二部分,因为我更熟悉 .NET 代码而不是 SQL。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-17
  • 1970-01-01
  • 2021-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多