2016-11-18 4 views
1

Я не могу найти что-нибудь, чтобы объяснить, почему при вызове SP, который делает вставки или обновления в зависимости от того, если записи уже существует на временные таблицы я получаюMS SQL временной таблица неудача обновления

модификации данных не удалась на системы- versioned table «MYDB.dbo.TemporalExample», поскольку время транзакции было раньше времени начала периода для затронутых записей.

какая доза это означает? Кажется, что это случается некоторое время, я задаюсь вопросом, не связано ли это с тем, что im работает многопоточный код и azure 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 

Update мой височной скрипт создания таблицы:

 

    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

Я не уверен, почему я бы не обновил его? В конце концов, это обычная таблица, в которой я не обновляю таблицу истории, это как в документах MS [link] (https://msdn.microsoft.com/en-gb/library/mt591019.aspx), но все же просто нормальное обновление метод, который вы используете, когда вам нужно обновить свои данные в вашей таблице. –

+0

oh ok получил его, я думал, что это таблица истории – TheGameiswar

ответ

0

Так я работал его ... кажется, что временные таблицы не играют хорошо с заправочной логикой. Я подозреваю, что потому, что я делаю несколько параллельных обновлений для таблицы параллельно; связанная с этим таблица истории отстает в своем обновлении настолько, что временная привязка вызывает сбой. Проблема в том, что мой код в одном потоке исправил проблему. Кажется странным, что временная таблица будет подвержена тому, что кажется почти условием гонки? Я знаю, что это не мой код, поскольку тот же код отлично работает для других таблиц. Поэтому я предполагаю, что мне придется придерживаться однопоточной логики до тех пор, пока MS не исправит ее.

+0

Вы вызываете (через сущность framework) процедуру с явной транзакцией? – Deadsheep39

+0

Я звоню с использованием рамки azure entity, которая поддерживает политику повтора и поддерживает методы async [link] (https://msdn.microsoft.com/en-us/library/dn456835 (v = vs.113).aspx) –

+0

Вы действительно имеете в виду переход от многопоточного к однопоточному, как при вставке последовательно, а не одновременно? Или вы имеете в виду переход от шаблона async/await к регулярным методам синхронизации? Я понимаю, что шаблон async/await связан с потоками, но просто хочу уточнить, что именно вы подразумеваете, сделав свой код однопоточным. –

0

Это хакерское обходное решение и не является идеальным в большинстве случаев, однако, если вы хотите сериализовать доступ к критическому разделу при работе с SQL-сервером то вы можете использовать встроенный механизм блокировки для предоставления доступа к этому критическому разделу через , однако вы можете просто перемещать узкое место в другое место в зависимости от ситуации.

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

yer проблема заключается в том, чтобы поддерживать метод async, который поставляется с лазурной структурой сущности. Я всегда могу использовать логику с одним потоком, но в идеале вы бы предположили, что временные таблицы будут работать с асинхронной логикой. Сказав, что я заметил, что вы не можете урезать вызов на временных таблицах, которые, как я думал, были странными, поэтому, возможно, они не поддерживают другие функции, такие как threading..but спасибо за предложение :) –

Смежные вопросы