bronckhorst Posted September 7, 2016 at 01:50 PM Report #598701 Posted September 7, 2016 at 01:50 PM Boa tarde. Em algumas ocasiões, a minha aplicação origina mensagens de erro do tipo "Transaction (Process ID 52) was deadlocked on lock | communication buffer resources with another process and has been chosen as the deadlock victim. Rerun the transaction." Estes erros ocorrem principalmente em comandos UPDATE, como por exemplo: UPDATE TOP (1) PRO.GeometriasCortadas SET status = 'T', mesatriagem = 'ert135', datatriagem = '2016-09-06 21:51:32' WHERE id_geometria = '157' AND codigoMP = 'AAV01CN0101' AND loteMP = 'A20942_9QH' AND subloteMP = '14998' AND status = 'C' AND IDCorteMeiasPeles <> '0' Conseguem dizer-me alguma forma de corrigir esta situação? Obrigado. Carlos Araújo.
M6 Posted September 7, 2016 at 02:07 PM Report #598702 Posted September 7, 2016 at 02:07 PM (edited) Tipicamente é por processo concorrencial em escrita sobre a tabela, mas sem mais informação é impossível de dizer. Podes começar por uma abordagem simples usando "with (rowlock)" no comando de update, forçando assim o lock apenas aos registos que vão ser atualizados e não à tabela. A abordagem menos simples é colocares o update isolado numa transação. A abordagem "correta" é analisares se é possível teres ai uma execução de código que tente, concorrencialmente, fazer lock aos mesmos registos mais de uma vez. Esqueci-me de referir que se te for possível, usa o profiler para ver o que se está a passar na base de dados e tentar perceber quem está a aceder a essa tabela e em que condições o faz. Edited September 7, 2016 at 02:09 PM by M6 Esqueci-me de referir o profiler. 1 Report 10 REM Generation 48K! 20 INPUT "URL:", A$ 30 IF A$(1 TO 4) = "HTTP" THEN PRINT "400 Bad Request": GOTO 50 40 PRINT "404 Not Found" 50 PRINT "./M6 @ Portugal a Programar."
jsWizard Posted September 7, 2016 at 02:10 PM Report #598703 Posted September 7, 2016 at 02:10 PM Um deadlock ocorre quando A espera por B e B espera por A. Exemplo: a tabela A tem um trigger que faz um update na tabela B e por sua vez a tabela B tem tb um trigger que faz update na tabela A. Ora, neste caso, pode ocorrer um deadlock se o(s) registos estiverem locked, a base de dados vai esperar X tempo e depois opta por matar a transacção. Este é um exemplo de má programação. Deadlocks podem tb ocorrer sem ser por má programação (evidente.. como no exemplo anterior).. pode uma transacção (T1) estar a fazer um lock X e outra transacção (T2) estar a fazer um lock Y. Se T1 necessita de alterar Y vai esperar que Y seja libertado.. mas se T2 necessita de alterar X, vai tb esperar.. e novamente temos um deadlock. É preciso ter atenção a referências circulares para evitar deadlock.. se for uma bd com muitos users em simultâneo.. pior ainda 😉
bronckhorst Posted September 15, 2016 at 04:30 PM Author Report #598893 Posted September 15, 2016 at 04:30 PM Em 07/09/2016 às 15:07, M6 disse: Tipicamente é por processo concorrencial em escrita sobre a tabela, mas sem mais informação é impossível de dizer. Podes começar por uma abordagem simples usando "with (rowlock)" no comando de update, forçando assim o lock apenas aos registos que vão ser atualizados e não à tabela. A abordagem menos simples é colocares o update isolado numa transação. A abordagem "correta" é analisares se é possível teres ai uma execução de código que tente, concorrencialmente, fazer lock aos mesmos registos mais de uma vez. Esqueci-me de referir que se te for possível, usa o profiler para ver o que se está a passar na base de dados e tentar perceber quem está a aceder a essa tabela e em que condições o faz. Obrigado pela resposta, M6. Tentei usar a designação "with (rowlock)" no update, mas continuo a receber mensagens de erro do mesmo género. Quando falas em colocar o update isolado numa transação, o que queres dizer com isso em concreto? Obrigado pela ajuda.
M6 Posted September 15, 2016 at 05:06 PM Report #598894 Posted September 15, 2016 at 05:06 PM Refiro-me a colocares todo o código SQL que estás a executar numa transação. Muito provavelmente esse update não é isolado, ocorre no meio de um conjunto de outras instruções de SQL. Todas essas instruções devem ser incluidas numa transação. Talvez seja boa ideia meteres o profiler a ver o que se está a passar, para veres de onde vêm e como chegam os pedidos de update para despistares o que está a acontecer. 10 REM Generation 48K! 20 INPUT "URL:", A$ 30 IF A$(1 TO 4) = "HTTP" THEN PRINT "400 Bad Request": GOTO 50 40 PRINT "404 Not Found" 50 PRINT "./M6 @ Portugal a Programar."
cusco Posted September 23, 2016 at 03:30 PM Report #599104 Posted September 23, 2016 at 03:30 PM WITH (NOLOCK) deves usar nos selects que usam a mesma tabela que estás a tentar actualizar. Assim o update não é "deadlock victim"
bronckhorst Posted September 27, 2016 at 09:09 AM Author Report #599163 Posted September 27, 2016 at 09:09 AM Bom dia. Através do SQL Profiler, descobri qual era o outro comando UPDATE que estava a originar o DEADLOCK com este UPDATE que referi. Usando WITH (ROWLOCK) em ambos os UPDATES,parece que consegui evitar o DEADLOCK... Pelo menos, não recebi mensagens de erro do género nos últimos dias. Muito obrigado pela vossa ajuda.
M6 Posted October 1, 2016 at 11:00 AM Report #599263 Posted October 1, 2016 at 11:00 AM Porreiro. No entanto, uma vez que já descobriste qual o conflito, aconselho-te a usares transações em ambos, desta forma garantes que não haverá dead locks quando ambos os comandos tentarem guardar a mesma linha simultaneamente.quais o 10 REM Generation 48K! 20 INPUT "URL:", A$ 30 IF A$(1 TO 4) = "HTTP" THEN PRINT "400 Bad Request": GOTO 50 40 PRINT "404 Not Found" 50 PRINT "./M6 @ Portugal a Programar."
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now