none
Update con Lock RRS feed

  • Domanda

  • Buongiorno e buon lavoro a tutti,
    SQL2014:

    ho questo problema:

    dalla mia procedura in TSQL aggiorno la tabella TEST e nella where c'è la PK della tabella stessa e fin qui tutto ok;

    Se tento, da un'altra sessione, di aggiornare la stessa tabella TEST, con una PK diversa naturalmente, non va rimane in attesa che termini la procedura in TSQL;

    La cosa ancor più strana è che solo con la Tabella TEST me lo fa, con altre tabelle funziona alla grande.

    Attendo vs gentilmente.

    Emanuele

    giovedì 21 gennaio 2016 09:26

Risposte

  • Ciao Emanuele,

    esiste un meccanismo noto con il nome Lock Escalation, che effettua la "conversione di un numero elevato di blocchi specifici in un numero inferiore di blocchi generici, in modo da diminuire l'overhead di sistema aumentando, contemporaneamente, la probabilità di contese di concorrenza".

    Se per la query #1, SQL Server decide di acquisire un lock sull'intera pagina o su un gruppo di pagine (piuttosto che un lock di riga), può accadere che vengano interessate dal lock anche le righe che vorrebbe leggere la query #2, nonostante siano righe diverse da quelle aggiornate con la query #1.

    Ciao


    Sergio Govoni

    SQL Server MVP
    MVP Profile | English Blog | Twitter | LinkedIn



    mercoledì 27 gennaio 2016 22:20
    Moderatore

Tutte le risposte

  • Ciao Emanuele,

    se le due righe che tenti di aggiornare risiedono nella stessa pagina di memoria (data page), e SQL Server ha scelto di applicare un lock di pagina per l'aggiornamento eseguito attraverso la tua procedura T-SQL, il secondo update attenderà il completamento del primo perchè di fatto sta cercando di aggiornare la stessa data page.

    Quando ti trovi in questa situazione prova ad eseguire la query seguente.. ti darà qualche informazione in più su cui ragionare:

    -- Richieste bloccate con informazioni sul testo
    -- del comando T-SQL e sul piano di esecuzione
    SELECT
      s.session_id
      ,r.blocking_session_id
      ,t.text
      ,p.query_plan
      ,s.login_time
      ,s.host_name
      ,s.program_name
      ,s.login_name
      ,s.status
      ,s.last_request_start_time
      ,s.reads
      ,s.logical_reads
      ,r.command
      ,r.wait_type
      ,r.wait_time
      ,r.open_transaction_count
      ,r.sql_handle
      ,r.query_plan_hash
    FROM
      sys.dm_exec_sessions s
    JOIN
      sys.dm_exec_requests r on r.session_id=s.session_id
    CROSS APPLY
      sys.dm_exec_sql_text(r.sql_handle) as t
    CROSS APPLY
      sys.dm_exec_query_plan(r.plan_handle) as p
    WHERE
      (s.is_user_process = 1)
      AND (r.blocking_session_id > 0);
    GO
    

    Ti segnalo anche la SP beta_lockinfo di Erland Sommarskog, con questa stored procedure puoi investigare meglio..

    Ciao!


    Sergio Govoni

    SQL Server MVP
    MVP Profile | English Blog | Twitter | LinkedIn

    giovedì 21 gennaio 2016 21:47
    Moderatore
  • Ciao Sergio e grazie,
    ho fatto le prove che mi hai consigliato:

    ecco cosa mi dice:

    si può far cambiare pagina di memoria ad SQL?

    Attendo tue grazie


    Emanuele

    venerdì 22 gennaio 2016 06:26
  • Ciao Emanuele,

    nell'immagine non si vede, ma presumo che nelle prime colonne estratte dalla query ci sia anche lo SPID del processo che sta bloccando la SELECT (colonna blocking_session_id).

    Cosa sta facendo quel processo? Se quel processo ha una transazione aperta e sta modificando i dati che la tua SELECT tenta di leggere, il livello di isolamento di default (READ_COMMITTED) impedisce la lettura di dati non committati.. la SELECT attende quindi il completamento (commit o rollback) della transazione aperta dall'altro processo..

    Ciao


    Sergio Govoni

    SQL Server MVP
    MVP Profile | English Blog | Twitter | LinkedIn


    venerdì 22 gennaio 2016 18:36
    Moderatore
  • Ciao Sergio, il fatto è che la query 2 x csoi dire NON sta tentando di leggere gli stessi record della query 1, per questo non capisco il perchè purtroppo trova la tabella lockata.

    ???


    Emanuele

    mercoledì 27 gennaio 2016 13:14
  • Ciao Emanuele,

    esiste un meccanismo noto con il nome Lock Escalation, che effettua la "conversione di un numero elevato di blocchi specifici in un numero inferiore di blocchi generici, in modo da diminuire l'overhead di sistema aumentando, contemporaneamente, la probabilità di contese di concorrenza".

    Se per la query #1, SQL Server decide di acquisire un lock sull'intera pagina o su un gruppo di pagine (piuttosto che un lock di riga), può accadere che vengano interessate dal lock anche le righe che vorrebbe leggere la query #2, nonostante siano righe diverse da quelle aggiornate con la query #1.

    Ciao


    Sergio Govoni

    SQL Server MVP
    MVP Profile | English Blog | Twitter | LinkedIn



    mercoledì 27 gennaio 2016 22:20
    Moderatore