Problema con deadlock (codigo de .net incluido)

23/11/2005 - 18:54 por Hugo Flores | Informe spam
Hola,

Estoy obteniendo un deadlock en mi BD
Antes que nada debo decir que mi BD esta en un Win XP Pro

El procedimeinto en el que tengo el deadlock es el siguiente:

PROCEDURE UpdateTestFields
@id_Test int,
@name varchar(255),
@value varchar(5000),
@lastModifiedBy varchar(50)
AS

UPDATE TestFields
SET value = @value,
lastModifiedBy = @lastModifiedBy,
lastModified = GETDATE()
WHERE id_Test = @id_Test
AND name = @name

Simple, pero la transacion la hago en el codigo de .net

Aqui esta el codigo:

Public Sub UpdateTestAndTestFields(ByVal intTestId As Int32, ByVal
oParent As Control, ByVal intApplicationNumber As Int32, _
ByVal intCustomerId As Int32, ByVal strLastModifiedBy
As String, ByVal strRemarks As String, _
ByVal enStatus As TestStatus, ByVal blnBlockUser As
Boolean, ByVal enBlockType As BlockType, _
ByVal strUnitNumber As String, ByVal strStationNumber
As String, ByVal strDistrictNumber As String, ByVal strDXName As
String)

Dim conn As New
SqlConnection(ConfigurationSettings.AppSettings("Connectionstring"))
Dim cmd As New SqlCommand

Dim oTrans As SqlTransaction

conn.Open()
cmd.Connection = conn
oTrans = conn.BeginTransaction
cmd.Transaction = oTrans
cmd.CommandType = CommandType.StoredProcedure

Try
For Each oControl As Control In oParent.Controls
cmd.Parameters.Clear()
Select Case oControl.GetType.Name
Case "TextBox"
Dim txtTemp As New TextBox

txtTemp = oControl
UpdateTestFieldsTrans(conn, cmd, intTestId,
txtTemp.ID, txtTemp.Text, strLastModifiedBy)
Case "RadioButtonList"
Dim rdoTemp As New RadioButtonList

rdoTemp = oControl
UpdateTestFieldsTrans(conn, cmd, intTestId,
rdoTemp.ID, rdoTemp.SelectedItem.Value, strLastModifiedBy)
End If
Case "CheckBox"
Dim chkTemp As New CheckBox

chkTemp = oControl
UpdateTestFieldsTrans(conn, cmd, intTestId,
chkTemp.ID, chkTemp.Checked, strLastModifiedBy)
End Select
Next
cmd.Parameters.Clear()
UpdateTestsTrans(conn, cmd, intCustomerId, intTestId,
enStatus, strRemarks, strLastModifiedBy, blnBlockUser, enBlockType,
strUnitNumber, strStationNumber, strDistrictNumber, strDXName)
oTrans.Commit()
Catch ex As Exception
oTrans.Rollback()
Finally
conn.Close()
End Try

End Sub

Como pueden ver tengo una pagina ASPX ya sea con un Textbox,
RadioButtonList o CheckBox, y los IDs de los controles estan guardados
en el campo name the mi tabla TestField en donde tengo que actualizar
su valor con el que obtenga del usuario.

El Sub UpdateTestFieldsTrans solamente tiene la llamada y ejecucion del
procedimiento que puse al principio, solo le estoy pasando el objeto
connection y el command para persistir la transaccion. Y el Sub
UpdateTestsTrans Sub es una llamada y ejecucion a otro procedimiento,
pero como el deadlock no ocurre ahi no veo la razon para ponerlo, ya
que solo haria mas grande este mensaje.

Las preguntas son:

Tengo el deadlock solo por que mi BD esta en WinXP Pro?
O simplemente estoy haciendo mal las cosas desde el codigo de .net?

Cualquier ayuda que me puedan dar, sera apreciada

Saludos
 

Leer las respuestas

#1 Victor Koch
23/11/2005 - 19:13 | Informe spam
Hola Hugo,

Tal vez seria bueno explicar que es eso de los deadlock o abrazo mortal.

Cuando uno inicia una transacción todos los registros actualizados dentro de
esa transacción son bloqueados por la transacción que lo actualizo y ninguna
otra conexión puede acceder a ellos, cuando se termina la transacción los
mismos son desbloqueados.
Ahora bien, supongamos que se produce esta secuencia:

Terminal uno comienza una transacción (T1)
Terminal dos comienza una transacción (T2)
T1 actualiza el campo stock de la tabla artículos cuyo ID del articulo es 1,
bloquea el registro 1
T1 sigue actualizando e insertando otro registros
T2 actualiza el campo stock de la tabla artículos cuyo ID del articulo es 2,
bloquea el registro 2
T2 sigue actualizando e insertando otro registros
T1 intenta leer la tabla artículos cuyo ID del articulo es 2, se queda
esperando porque el ID = 2 lo actualizo y bloqueo T2
T2 intenta leer la tabla artículos cuyo ID del articulo es 1, se queda
esperando porque el ID = 1 lo actualizo y bloqueo T1

Se entro en un callejón sin salida o en un loop, ninguna de las dos
transacciones puede continuar, alguien debe morir !!, el motor mata una de
las transacciones para que la otra pueda continuar, es por ese motivo es que
recibís el error.

Un saludo, Víctor Koch.


"Hugo Flores" escribió en el mensaje
news:
Hola,

Estoy obteniendo un deadlock en mi BD
Antes que nada debo decir que mi BD esta en un Win XP Pro

El procedimeinto en el que tengo el deadlock es el siguiente:

PROCEDURE UpdateTestFields
@id_Test int,
@name varchar(255),
@value varchar(5000),
@lastModifiedBy varchar(50)
AS

UPDATE TestFields
SET value = @value,
lastModifiedBy = @lastModifiedBy,
lastModified = GETDATE()
WHERE id_Test = @id_Test
AND name = @name

Simple, pero la transacion la hago en el codigo de .net

Aqui esta el codigo:

Public Sub UpdateTestAndTestFields(ByVal intTestId As Int32, ByVal
oParent As Control, ByVal intApplicationNumber As Int32, _
ByVal intCustomerId As Int32, ByVal strLastModifiedBy
As String, ByVal strRemarks As String, _
ByVal enStatus As TestStatus, ByVal blnBlockUser As
Boolean, ByVal enBlockType As BlockType, _
ByVal strUnitNumber As String, ByVal strStationNumber
As String, ByVal strDistrictNumber As String, ByVal strDXName As
String)

Dim conn As New
SqlConnection(ConfigurationSettings.AppSettings("Connectionstring"))
Dim cmd As New SqlCommand

Dim oTrans As SqlTransaction

conn.Open()
cmd.Connection = conn
oTrans = conn.BeginTransaction
cmd.Transaction = oTrans
cmd.CommandType = CommandType.StoredProcedure

Try
For Each oControl As Control In oParent.Controls
cmd.Parameters.Clear()
Select Case oControl.GetType.Name
Case "TextBox"
Dim txtTemp As New TextBox

txtTemp = oControl
UpdateTestFieldsTrans(conn, cmd, intTestId,
txtTemp.ID, txtTemp.Text, strLastModifiedBy)
Case "RadioButtonList"
Dim rdoTemp As New RadioButtonList

rdoTemp = oControl
UpdateTestFieldsTrans(conn, cmd, intTestId,
rdoTemp.ID, rdoTemp.SelectedItem.Value, strLastModifiedBy)
End If
Case "CheckBox"
Dim chkTemp As New CheckBox

chkTemp = oControl
UpdateTestFieldsTrans(conn, cmd, intTestId,
chkTemp.ID, chkTemp.Checked, strLastModifiedBy)
End Select
Next
cmd.Parameters.Clear()
UpdateTestsTrans(conn, cmd, intCustomerId, intTestId,
enStatus, strRemarks, strLastModifiedBy, blnBlockUser, enBlockType,
strUnitNumber, strStationNumber, strDistrictNumber, strDXName)
oTrans.Commit()
Catch ex As Exception
oTrans.Rollback()
Finally
conn.Close()
End Try

End Sub

Como pueden ver tengo una pagina ASPX ya sea con un Textbox,
RadioButtonList o CheckBox, y los IDs de los controles estan guardados
en el campo name the mi tabla TestField en donde tengo que actualizar
su valor con el que obtenga del usuario.

El Sub UpdateTestFieldsTrans solamente tiene la llamada y ejecucion del
procedimiento que puse al principio, solo le estoy pasando el objeto
connection y el command para persistir la transaccion. Y el Sub
UpdateTestsTrans Sub es una llamada y ejecucion a otro procedimiento,
pero como el deadlock no ocurre ahi no veo la razon para ponerlo, ya
que solo haria mas grande este mensaje.

Las preguntas son:

Tengo el deadlock solo por que mi BD esta en WinXP Pro?
O simplemente estoy haciendo mal las cosas desde el codigo de .net?

Cualquier ayuda que me puedan dar, sera apreciada

Saludos

Preguntas similares