Тупик в SQL 2008 при вставке и обновлении - PullRequest
1 голос
/ 25 марта 2011

Я захожу в тупик для одновременных пользователей для вставки в мою таблицу. SP, который я запускаю, относительно прост

SET NOCOUNT ON;

begin try
    begin tran

    DECLARE @idoc INT
    declare @ProcessedResponse table (
      candidateInstanceID  int,
      assessmetID          int,
      sectionID            int,
      itemID               int,
      clientID             int,
      displayTypeID        int,
      respondedAt          datetime,
      responseTime         float,
      marksObtained        float,
      processedresponseXML xml,
      resultDescription    varchar(255),
      reportedIssue        bit )

    -- insert into @PartialResponse 
    EXEC sp_xml_preparedocument
      @idoc OUTPUT,
      @Processed_Responses

    insert into @ProcessedResponse
    SELECT *
    FROM   OPENXML(@idoc, '/Processed_Responses/Processed_Response', 1)
              WITH (Candidate_Instance_ID int,
                    Assessment_ID         int,
                    Section_ID            int,
                    Item_ID               int,
                    Client_ID             int,
                    Display_Type_ID       int,
                    Responded_At          datetime,
                    Response_Time         float,
                    Marks_Obtained        float,
                    Processed_XML         text,
                    Result_Description    text,
                    Reported_Issue        bit)

    INSERT INTO Processed_Response
                (Candidate_Instance_ID,
                 Assessment_ID,
                 Section_ID,
                 Client_ID,
                 Item_ID,
                 Display_Type_ID,
                 Responded_At,
                 Response_Time,
                 Marks_Obtained,
                 Processed_XML,
                 Result_Description,
                 Reported_Issue)
    SELECT pr.candidateInstanceID,
           pr.assessmetID,
           pr.sectionID,
           pr.clientID,
           pr.itemID,
           pr.displayTypeID,
           cast(pr.respondedAt as datetime),
           pr.responseTime,
           case pr.marksObtained
             when 0 then null
             else pr.marksObtained
           end,
           CAST(pr.processedresponseXML AS XML),
           pr.resultDescription,
           pr.reportedIssue
    FROM   @ProcessedResponse pr

    update pr
    set    pr.Client_ID = a.Assessment_Owner
    from   Processed_Response pr
           join Assessment a
             on pr.Assessment_ID = a.Assessment_Id
    where  pr.Candidate_Instance_ID = @Candidate_Instance_ID

    update Candidate_Instance
    set    Instance_Status = 'Completed',
           Instance_End_Time = GETDATE()
    where  Candidate_Instance_Id = @Candidate_Instance_ID

    commit tran
end try

begin catch
    DECLARE @ErrorMessage NVARCHAR(4000);
    DECLARE @ErrorSeverity INT;
    DECLARE @ErrorState INT;

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

    rollback tran

    -- 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  

Может кто-нибудь помочь мне спасибо.

1 Ответ

0 голосов
/ 25 марта 2011

требуется два бита кода для взаимоблокировки, так что же этот код сам блокируется?Это трудно диагностировать, не зная структуры таблиц и использования индекса.Ваша таблица выбора обновлений (update pr...) сканирует и блокирует всю таблицу?и т.д.

без сомнения, я бы переместил BEGIN TRANS прямо перед INSERT INTO Processed_Response, вам не нужно помещать все локальные переменные в транзакцию.Сделайте ваши транзакции как можно короче.

Настройте SQL Server Profiler и получите трассировку графа мертвых блокировок, и вы увидите две части SQL, которые бьют друг друга, и идете оттуда.1008 *

...