5

編集問題は別のものだったので、この質問はもはや有効ではありません。私の答えの下にある私の説明を見てください。

エチケットがわからないので、この質問は現状のままにしておきます

テーブルにデータを書き込むストアド プロシージャがあります。

ストアド プロシージャの呼び出しに Microsoft Practices Enterprise ライブラリを使用しています。ExecuteNonQuery への呼び出しを使用して、ストアド プロシージャを呼び出します。

ExecuteNonQuery が返された後、サード パーティのライブラリを呼び出します。約 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

1

私はあなたが言及したデータアクセスツールに精通していませんが、あなたの説明から、次のステップに進む前にプロセスがストアドプロシージャの実行が完了するのを待たないか、古い「何か他のもの」が混乱していると推測します書き込み呼び出しと読み取り呼び出しの間にデータを入れます。

何が起こっているかを知る 1 つの方法は、SQL プロファイラーを使用することです。それを起動し、データベースで発生する可能性のあるすべてのクエリ実行イベント (ストアド プロシージャおよびストアド プロシージャ行の開始/停止イベントを含む) を監視し、テキスト列と開始/終了列を監視し、これをアプリケーションのトレース中に表示される時間と関連付けます。そこで何が起こっているのかを理解するのに役立つはずです。(SQL プロファイラーの使用は複雑な場合がありますが、Web 上にはそれを説明する多くの情報源があり、その使用方法を学ぶ価値は十分にあります。)

于 2013-04-25T14:03:08.583 に答える
0

コメントがあるので、以下に私の答えを残しておきます...

わかりました、質問を単純化しすぎたことを残念に思います。実際に起こったことは次の 2 点です。

1)挿入手順は実際には別のマシン(分散システム)で実行されています。
2) 挿入プロシージャは、実際にはトランザクションなしで 2 つのテーブルにデータを挿入します。

これは、クエリを同時に実行して、1 つのテーブルが書き込まれ、2 番目のテーブルにはまだ書き込みがコミットされていない状態のテーブルを見つけることができることを意味します。

読み取りクエリは書き込みなしまたは完全書き込みのいずれの場合も処理できますが、一方のテーブルに書き込みがあり、もう一方のテーブルに保留中のコミットがある場合は処理できないため、単純なトランザクションでこれを修正します。

ストアド プロシージャを作成すると、MSSQLadmin ツールが既定で次の行を追加したことがわかりました。

SET NOCOUNT ON;

それを次のようにすると:

SET NOCOUNT OFF;

次に、私の手順は実際にデータベースに適切にコミットします。このデフォルトが実際に問題を引き起こすのは奇妙です。

于 2013-04-26T15:16:18.043 に答える