1

这是我第一次在 stackoverflow 中提问 :) 我有一个用 C# 开发的中型 winforms 应用程序,它连接到 SQL Server 2008,这个应用程序旨在成为一个业务管理应用程序(用于中间公司),您可以制作报价单、发票, 等等。

关键是有时(并非总是)一台计算机中的一个用户创建一个报价,该报价存储在 SQL 中,并接收一个 ID 作为结果。然后,同时另一台不同计算机中的另一个用户创建另一个报价,并收到相同的 ID,因此最后一个报价与第一个报价重叠。

这种情况不会经常发生,但是会发生,我找不到原因,也许最好的方法是确保数据的个性化,你们中的一些人可以给我一些启发。

事实是:它总是发生在两个确切的人身上(我们有 6 个销售人员,这个问题总是发生在同一个销售人员身上)其中一个销售人员正在使用远程桌面远程处理我的应用程序,所以,那个应用程序的实例正在服务器中运行 其他销售人员正在他自己的计算机上本地使用该应用程序,该计算机位于安装服务器的同一网络中。

存储数据的过程如下:

在数据库结构中,您将找到以下 3 个表:1) 报价的“数据标题” 2) 报价的“详细信息” 3) 与报告问题相关的报价的表详细信息

1)创建报价并按下“接受”按钮后,应用程序获取“数据标题”并存储它,结果,它返回一个 ID(不是数据库的 ID,而是一个源自某些公司政策的 ID) 2)返回 id,应用程序开始将“详细信息”存储在第二个表中 3)如果用户想要打印报价,则创建一个报告,为此我临时“复制”详细信息中的详细数据表到报告表

发生错误时,我查询数据库,发现只注册了一个引用(最后一个),所以,我知道最后一个引用与第一个重叠。

乍一看,问题可能与我生成将由 SQL 返回的 ID 的方式有关,我创建的方式实际上很简单: - 我检查分配给创建 Quote 的 ID 的最后一个数字并注册加一 - 如果没有number 存在(表中的第一个数据)我只是分配一个作为初始 ID

为什么不将表键作为 ID?因为系统需要与另一个系统通信,并且他们需要来自一系列 ID 的特定 ID

创建 ID 的存储过程中的代码如下:

BEGIN TRAN
DECLARE @newNumDoc INT
SET @newNumDoc = (ISNULL((SELECT MAX(NUMDOC) FROM REMISION_DBF WHERE idEmpresa = @idEmpresa),0) + 1)
IF @newNumDoc IS NULL
    SET @newNumDoc = 1
COMMIT TRAN

那么,任何人都可以帮助我了解问题出在哪里,或者至少改变焦点以确保不会错过任何重叠的数据?

4

1 回答 1

0

问题在于您处理交易的方式,以及应该包含在其中的代码。您的交易目前涵盖以下 SQL:

  • 从数据库表中获取最高的 NUMDOC 值
  • 如果为空,则将其设置为 1。

但是,这并不真正具有交易价值,因为您在任何时候都不会插入另一条记录。没有理由为什么不能出现另一个进程并获得完全相同的数字 - 事实上,这就是您所看到的。

您需要做的更多是以下方面:

BEGIN TRAN
DECLARE @newNumDoc INT
SET @newNumDoc = (ISNULL((SELECT MAX(NUMDOC) FROM REMISION_DBF WHERE idEmpresa = @idEmpresa),0) + 1)
IF @newNumDoc IS NULL SET @newNumDoc = 1
INSERT INTO REMISION_DBF (NUMDOC) VALUES (@newNumbDoc)
COMMIT TRAN

这将确保您NUMDOC为当前进程保留,然后在写入数据时,您只需将当前进程切换INSERTUPDATE.

(这显然可能会给您的系统带来其他需要单独解决的问题,但它会为您提供一个起点,同时确保NUMDOC值的唯一性。

当然,还有其他选择;例如,一种可能性是使用单独的“保留”表来避免对REMISION_DBF. 但即便如此,同样的…………BEGIN TRAN模型也适用。)GETINSERTCOMMIT

于 2013-09-05T22:07:48.747 回答