这是我第一次在stackoverflow中询问:) 我有一个用C#开发的中型winforms应用程序连接到SQL Server 2008,该应用程序旨在成为一个商业管理应用程序(对于中间公司),您可以制作报价单,发票等。
关键是,有时(并非总是)一台计算机中的一个用户创建一个Quote,Quote会存储在SQL中,并接收一个ID作为结果。 然后,同时另一个不同计算机中的另一个用户创建另一个Quote,并且,收到相同的ID,结果这个最后一个引用与第一个引用重叠。
这种情况不会经常发生,但它发生了,我找不到原因,或许最好的方法是确保数据的个性化,你们中的一些人可以为我带来一些亮点。
事实是: 它总是发生在两个确切的人(我们有6个销售人员,这个问题总是发生在同一个2销售人员) 其中一个销售人员使用远程桌面远程处理我的应用程序,因此该应用程序的实例正在服务器中运行 另一位销售人员正在他自己的计算机上本地使用该应用程序,该服务器位于安装服务器的同一网络中。
存储数据的过程如下:
在数据库结构中,您将找到3个表格如下: 1)报价的“数据标题” 2)报价的“细节” 3)与报告问题相关联的报价表格详细信息
1)创建引用并按下“接受”按钮后,应用程序获取“数据标题”并存储它,结果,它返回一个ID(不是数据库的ID,而是一个ID来源于某些ID)公司的政策) 2)随着id返回,应用程序开始在第二个表中存储“detail” 3)如果用户想要打印报价,则会创建一个报表,为此我会将详细信息表中的详细数据“临时复制”到报表中
当错误发生时,我查询数据库,我发现只有一个Quote(最后一个)被注册,所以,我知道最后一个引用与第一个引用重叠。
乍一看问题可能与我生成将由SQL返回的ID的方式有关,我创建的方式实际上非常简单: - 我检查分配的最后一个号码以创建Quote的ID并注册加一 - 如果不存在数字(表中的第一个数据),我只指定一个作为初始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
那么,任何人都可以帮助我了解问题所在或至少改变焦点以确保不会错过任何重叠数据吗?
答案 0 :(得分:0)
问题在于您处理事务的方式,以及应该在其中的代码。您的事务当前涵盖以下SQL:
但是,这不是真正的交易,因为在任何时候你都不会插入另一条记录。没有理由为什么另一个过程不能出现并获得完全相同的数字 - 事实上,这就是你所看到的。
您需要做的更多的是以下几点:
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
保留用于当前流程,然后在编写数据时,只需将当前INSERT
切换为UPDATE
。
(这可能会显然引发您的系统需要单独解决的其他问题,但它会为您提供一个起点,同时确保NUMDOC
值的唯一性。
当然,还有其他选择;例如,一种可能性是使用单独的“保留”表来避免REMISION_DBF
的污染。但即便如此,相同的BEGIN TRAN
... GET
... INSERT
... COMMIT
模型也适用。)