2016-11-18 3 views
1

私はレコードがすでに一時的なテーブルの上に存在するかどうかに応じて、挿入または更新を行うSPを呼び出すときに、私はMS SQL一時テーブルの更新に失敗

データ変更がシステム - に失敗した取得理由を説明するために何かを見つける傾けます影響を受けるレコードの開始時間が よりも前だったため、バージョン管理されたテーブル 'MYDB.dbo.TemporalExample'です。

どのような用量ですか?それはいくつかの時間が発生するように見えます、私はそのマルチスレッドコードと紺碧のSQLを実行しているので、同じテーブルに相互接続が好きではない場合一時的なもの?イムは、エンティティフレームワーク(最新バージョン)にもかかわらず行くが、私はそれがちょうどこの

 

create PROCEDURE mysp 
    @ID bigint, 
    @a FLOAT, 
    @b NVARCHAR(10), 
    @c DECIMAL(19, 4) 
AS 
    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED  

    SET NOCOUNT ON  

    BEGIN TRY 

     IF EXISTS (SELECT TOP 1 
         Id 
        FROM 
         my_Temporal_Table WITH (NOLOCK) 
        WHERE 
         id = @ID 
         AND a = @a 
         AND b = @b) 
      BEGIN 

       UPDATE 
        my_Temporal_Table 
       SET 
        Id = @ID, 
        a = @a, 
        b = @b 
        c = @c 
        DateModified = GETUTCDATE() 
       WHERE 
        Id = @Id 

      END 
     ELSE  
      BEGIN 

       INSERT INTO 
        my_Temporal_Table 
         (Id, a, b, c, DateModified) 
       VALUES 
         (@ID, @a, @b, @c , GETUTCDATE())   
      END 

    END TRY 
    BEGIN CATCH 
     DECLARE @ErrorMessage NVARCHAR(4000), 
       @ErrorSeverity INT, 
       @ErrorState  INT 

     SELECT 
       @ErrorMessage = ERROR_MESSAGE(),   
       @ErrorSeverity = ERROR_SEVERITY(), 
       @ErrorState = ERROR_STATE() 

     -- Use RAISERROR inside the CATCH block to return error 
     -- information about the original error that caused 
     -- execution to jump to the CATCH block. 
     RAISERROR (@ErrorMessage, -- Message text. 
        @ErrorSeverity, -- Severity. 
        @ErrorState -- State. 
        ) 

    END CATCH 

問題

私のSPの疑い更新 私の一時的なテーブル作成スクリプト:

 

    CREATE TABLE [Temporal](
    [TemporalId] [bigint] IDENTITY(1,1) NOT NULL, 
    [Payment] [decimal](19, 4) NOT NULL, 
    [DateModified] [datetime2](7) NOT NULL, 
    [SysStartTime] [datetime2](7) GENERATED ALWAYS AS ROW START NOT NULL, 
    [SysEndTime] [datetime2](7) GENERATED ALWAYS AS ROW END NOT NULL, 
    CONSTRAINT [TemporalId] PRIMARY KEY CLUSTERED ([TemporalId] ASC) 
     WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON), 
    PERIOD FOR SYSTEM_TIME ([SysStartTime], [SysEndTime]) 
    )WITH(
    SYSTEM_VERSIONING = ON (HISTORY_TABLE = [Car2].[TemporalHistory]) 
    ) 

を誰かが説明できますどうして私はこの問題を、なぜ意味するのか、もっと重要なのはどのように修正することができるのでしょうか?

おかげ

+0

なぜ一時テーブルを更新していますか – TheGameiswar

+0

なぜ私はそれを更新しないのか分かりませんか?結局のところ、通常のテーブルです。私はhistoryテーブルを更新していません。それはMS docs [link](https://msdn.microsoft.com/en-gb/library/mt591019.aspx)によるものです。あなたのテーブルのデータを更新する必要があるときに使用する方法 –

+0

ああ、それは私がそれがヒストリーテーブルだと思ったそれを得た – TheGameiswar

答えて

0

ので、私はそれを働いた...一時的なテーブルがスレッド・ロジックとうまく再生されないようです。私は、並行してテーブルに複数の同時更新を行っているので、それが疑わしい。リンクされている履歴テーブルの更新が遅れているため、時間の連動によって障害が発生します。私のコードをシングルスレッド化して問題を解決しました。時間的なテーブルは、ほぼ競争状態にあると思われるものの対象となるのは奇妙なようです。私は同じコードが他のテーブルでうまく動作するので、私のコードではないことを知っています。だから私はMSがそれを修正するまで単一スレッドのロジックに固執する必要があると思います

+0

(エンティティフレームワーク経由で)明示的なトランザクションでプロシージャを呼び出しますか? – Deadsheep39

+0

私は再試行ポリシーをサポートし、非同期メソッドをサポートするAzureエンティティフレームワークを使用して呼び出します。 [link](https://msdn.microsoft.com/en-us/library/dn456835(v=,113))aspx) –

+0

あなたは実際に、マルチスレッドからシングルスレッドへの移行を意味しますか?あるいは、async/awaitパターンから通常のsyncメソッドに移行することを意味しますか?私は非同期/待機パターンがスレッドに関連していることを認識していますが、コードをシングルスレッド化することによって、正確に何を意味するのかを明確にしたいだけです。 –

0

これはハックのある回避策ですが、SQL Serverを扱うときにクリティカルセクションへのアクセスをシリアル化したい場合はほとんどの場合組み込みのロック機構を使用して経由でそのクリティカルセクションへのアクセスを許可することができますが、状況に応じて別の場所にボトルネックを移動している可能性があります。

CREATE PROC MyCriticalWork(@MyParam INT)  
AS 
    DECLARE @LockRequestResult INT=0  
    DECLARE @MyTimeoutMiliseconds INT=5000--Wait only five seconds max then timeouit 

    BEGIN TRAN 

    EXEC @LockRequestResult=SP_GETAPPLOCK 'MyCriticalWork','Exclusive','Transaction',@MyTimeoutMiliseconds 
    IF(@LockRequestResult>=0)BEGIN 

      /* 
      DO YOUR CRITICAL READS AND WRITES HERE 
      */ 

     COMMIT TRAN--Releases the lock 
    END ELSE 
     ROLLBACK TRAN--Releases the lock 
+0

のメソッド呼び出しを同期メソッドに変更しました。全体的なポイントは、紺エンティティフレームワークに付属する非同期メソッドをサポートすることでした。私はいつもシングルスレッドロジックを使うことができますが、一時テーブルが非同期ロジックで動作することが理想的です。私は奇妙だと思っていた一時的なテーブルで切り捨てることができないと気づいたと言いますが、おそらく彼らはスレッドのような他の機能をサポートしていません。 –

関連する問題