5

编辑这个问题不再有效,因为问题是别的。请在我的回答中查看下面的解释。

我不确定礼仪,所以我将把这个问题留在当前状态

我有一个将一些数据写入表的存储过程。

我正在使用 Microsoft Practices Enterprise 库进行存储过程调用。我使用对 ExecuteNonQuery 的调用来调用存储过程。

在 ExecuteNonQuery 返回后,我调用了第 3 方库。它会在大约 100 毫秒后在一个单独的线程上回叫我。

然后我调用另一个存储过程来提取我刚刚编写的数据。在大约 99% 的情况下,数据会返回。有时它不返回任何行(即它找不到数据)。如果我在调试器中设置条件断点来检测这种情况并手动重新运行存储过程,它总是返回我的数据。

这让我相信写入存储过程正在工作,只是在调用时没有提交。

当谈到 sql 时,我是相当新手,所以我完全有可能做错了什么。我原以为写入存储过程会阻塞,直到其内容提交到数据库。

编写存储过程

 ALTER PROCEDURE [dbo].[spWrite] 
    @guid varchar(50),
        @data varchar(50)
    AS
    BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

-- see if this guid has already been added to the table
DECLARE @foundGuid varchar(50);
SELECT @foundGuid = [guid] from [dbo].[Details] where [guid] = @guid; 
    IF @foundGuid IS NULL
    -- first time we've seen this guid
    INSERT INTO [dbo].[Details] ( [guid], data ) VALUES (@guid, @data)
ELSE
    -- updaeting or verifying order
    UPDATE [dbo].[Details]  SET data =@data WHERE [guid] = @guid
END


SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

读取存储过程

ALTER PROCEDURE [dbo].[spRead] 
@guid varchar(50)   
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

SELECT * from [dbo].[Details] where [guid] = @guid; 
END 
4

3 回答 3

4

要实际阻止其他事务并手动提交,可能会添加

BEGIN TRANSACTION
--place your
--transactions you wish to do here

--if everything was okay
COMMIT TRANSACTION
--or
--ROLLBACK TRANSACTION if something went wrong

可以帮助你吗?

于 2013-04-25T13:45:34.553 回答
1

我不熟悉您提到的数据访问工具,但是从您的描述中,我猜想要么该过程不等待存储过程完成执行,然后再继续执行下一步,要么您的“其他东西”正在搞砸与您的写入和读取调用之间的数据。

判断发生了什么的一种方法是使用 SQL Profiler。启动它,监视数据库上所有可能的查询执行事件(包括存储过程和存储过程行开始/停止事件),观察 Text 和 Started/Ended 列,将其与跟踪应用程序时看到的时间相关联,以及这应该可以帮助您弄清楚那里发生了什么。(SQL Profiler 使用起来可能很复杂,但是网络上有很多解释它的资源,学习如何使用它非常值得。)

于 2013-04-25T14:03:08.583 回答
0

我会在下面留下我的答案,因为有评论...

好吧,我觉得我的问题过于简化了。实际发生的是两件事:

1)插入过程实际上是在单独的机器(分布式系统)上运行的。
2)插入过程实际上是在没有事务的情况下将数据插入到两个表中。

这意味着查询可以同时运行并找到处于其中一个已写入但第二个表尚未提交其写入的状态的表。

一个简单的事务解决了这个问题,因为读取查询可以处理无写入或完全写入的情况,但无法处理一个表已写入而另一个表有待提交的情况。

事实证明,当我创建存储过程时,MSSQLadmin 工具默认添加了一行:

SET NOCOUNT ON;

如果我把它变成:

SET NOCOUNT OFF;

然后我的程序实际上正确地提交到数据库。奇怪的是,这个默认值实际上最终会导致问题。

于 2013-04-26T15:16:18.043 回答