如何立即提交存储过程?

时间:2013-04-25 13:21:49

标签: sql-server acid

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

我不确定这个礼节所以我将这个问题留在“现状”

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

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

在ExecuteNonQuery返回后,我调用第三方库。它在大约100毫秒内在一个单独的线程上回复给我。

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

这让我相信写入存储过程只是在被调用时才提交。

对于sql我是相当新手,所以我完全有可能做错了。我原以为写入存储过程会阻塞,直到其内容被提交给db。

编写存储过程

 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 

3 个答案:

答案 0 :(得分:4)

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

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

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

可以帮到你吗?

答案 1 :(得分:1)

我不熟悉你提到的数据访问工具,但是根据你的描述,我猜这个进程不会等待存储过程完成执行,然后再进行下一步,或者你会发现“其他的东西” “正在弄乱你的写和来电之间的数据。

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

答案 2 :(得分:0)

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

好的,我感到羞耻我过分简化了我的问题。实际发生的是两件事:

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

这意味着查询可以同时运行,并在一个已写入的状态下查找表,而第二个表尚未“已提交写入”。

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

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

SET NOCOUNT ON;

如果我把它变成:

SET NOCOUNT OFF;

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