[英]Transactions in vb.net locks table and SELECT gets timeout
I have the following problem: Inside one sqltransaction in vb.net I INSERT data into several tables. 我有以下问题:在vb.net的一个sqltransaction中,我将数据插入到多个表中。
it is something like this: 它是这样的:
...
sqltransaction = connection.begintransaction
INSERT into table1
...
for i=1 to x
...
INSERT into table2
...
SELECT FROM table3
...
INSERT into table3
...
next i
sqltransaction.commit
...
Private Sub salveazaCerereaDeOferta()
If checkCompletion() = 1 Then
Dim conn As New SqlConnection(My.Settings.GestiuneService2012_beSQLConnectionString)
conn.Open()
Dim sqlTrans As SqlTransaction = conn.BeginTransaction()
Try
Dim cmdInsertCerereOferta As SqlCommand = conn.CreateCommand
cmdInsertCerereOferta.Transaction = sqlTrans
cmdInsertCerereOferta.CommandText = "INSERT INTO ListaCereriOferte (IDFurnizor,NrCerereOferta,DataCerereOferta,IDModTransCerereOferta,ObservatiiCerereOferta)" + _
" VALUES (@IDFurnizor,@NrCerereOferta,@DataCerereOferta,@IDModTransCerereOferta,@ObservatiiCerereOferta);" + _
" SELECT SCOPE_IDENTITY();"
cmdInsertCerereOferta.Parameters.Add("@IDFurnizor", SqlDbType.Int).Value = CInt(Me.t_IDFurnizor.Text)
cmdInsertCerereOferta.Parameters.Add("@NrCerereOferta", SqlDbType.Int).Value = CInt(Me.t_NumarCerereOferta.Text)
cmdInsertCerereOferta.Parameters.Add("@DataCerereOferta", SqlDbType.Date).Value = CDate(Me.t_DataCerereOferta.Text)
cmdInsertCerereOferta.Parameters.Add("@IDModTransCerereOferta", SqlDbType.Int).Value = 1
cmdInsertCerereOferta.Parameters.Add("@ObservatiiCerereOferta", SqlDbType.NVarChar).Value = Me.t_ObservatiiCerereOferta.Text
Dim IDCerereOferta As Integer = cmdInsertCerereOferta.ExecuteScalar
Dim ListaPieseCerereOferta = Me.CerereOfertaDataSet.ListaPieseCerereOferta.AsEnumerable
Dim ListaNecesarePePiesa = Me.CerereOfertaDataSet.NecesarePeOferta.AsEnumerable
Dim PieseOferta = From q In ListaPieseCerereOferta _
Select q
Dim cantTotalaPiese = Aggregate q In ListaPieseCerereOferta _
Into Sum(q.Cantitate)
Dim salvat As Integer = 0
Dim curIDPiesaDeSchimb As Integer
For Each piesa In PieseOferta
curIDPiesaDeSchimb = piesa.IDPiesaDeSchimb
Dim NecesarePePiesa = From p In ListaNecesarePePiesa _
Select p _
Order By p.IDNecesar Descending
Dim curIDNecesar As Integer
For Each necesar In NecesarePePiesa
curIDNecesar = necesar.IDNecesar
Dim cmdInsertPiesaCerereOferta As SqlCommand = conn.CreateCommand
cmdInsertPiesaCerereOferta.Transaction = sqlTrans
cmdInsertPiesaCerereOferta.CommandText = "INSERT INTO CereriOferte (IDCerereOferta,IDPiesaDeSchimb,Cantitate,UM,Observatii)" + _
" VALUES (@IDCerereOferta,@IDPiesaDeSchimb,@Cantitate,@UM,@Observatii);" + _
" SELECT SCOPE_IDENTITY();"
cmdInsertPiesaCerereOferta.Parameters.Add("@IDCerereOferta", SqlDbType.Int)
cmdInsertPiesaCerereOferta.Parameters.Add("@IDPiesaDeSchimb", SqlDbType.Int)
cmdInsertPiesaCerereOferta.Parameters.Add("@Cantitate", SqlDbType.Float)
cmdInsertPiesaCerereOferta.Parameters.Add("@UM", SqlDbType.NVarChar)
cmdInsertPiesaCerereOferta.Parameters.Add("@Observatii", SqlDbType.NVarChar)
Dim cmdInsertNecesarCerereOferta As SqlCommand = conn.CreateCommand
cmdInsertNecesarCerereOferta.Transaction = sqlTrans
cmdInsertNecesarCerereOferta.CommandText = "INSERT INTO NecesareCereriOferte (IDPiesaNecesar,IDPiesaCerereOferta)" + _
" VALUES (@IDPiesaNecesar,@IDPiesaCerereOferta)"
cmdInsertNecesarCerereOferta.Parameters.Add("@IDPiesaNecesar", SqlDbType.Int)
cmdInsertNecesarCerereOferta.Parameters.Add("@IDPiesaCerereOferta", SqlDbType.Int)
Select Case curIDNecesar
Case 0
cmdInsertPiesaCerereOferta.Parameters("@IDCerereOferta").Value = IDCerereOferta
cmdInsertPiesaCerereOferta.Parameters("@IDPiesaDeSchimb").Value = curIDPiesaDeSchimb
cmdInsertPiesaCerereOferta.Parameters("@Cantitate").Value = 1
cmdInsertPiesaCerereOferta.Parameters("@UM").Value = piesa.UM
cmdInsertPiesaCerereOferta.Parameters("@Observatii").Value = ""
For i = 1 To necesar.Cantitate
cmdInsertPiesaCerereOferta.ExecuteNonQuery()
salvat += 1
Me.tsspb_SalvareCerereOferta.Value = CInt(100 * salvat / cantTotalaPiese)
Next
Case Is > 0
Me.PieseNecesarePeOfertaTableAdapter.Fill(Me.CerereOfertaDataSet.PieseNecesarePeOferta, curIDNecesar, curIDPiesaDeSchimb, CInt(necesar.Cantitate))
Dim ListaPieseNecesarePeOferta = Me.CerereOfertaDataSet.PieseNecesarePeOferta.AsEnumerable
Dim PieseNecesareOferta = From q In ListaPieseNecesarePeOferta _
Select q
For i = 1 To necesar.Cantitate
cmdInsertPiesaCerereOferta.Parameters("@IDCerereOferta").Value = IDCerereOferta
cmdInsertPiesaCerereOferta.Parameters("@IDPiesaDeSchimb").Value = curIDPiesaDeSchimb
cmdInsertPiesaCerereOferta.Parameters("@Cantitate").Value = 1
cmdInsertPiesaCerereOferta.Parameters("@UM").Value = piesa.UM
cmdInsertPiesaCerereOferta.Parameters("@Observatii").Value = ""
Dim insertedIDPiesaCerereOferta As Integer = cmdInsertPiesaCerereOferta.ExecuteScalar
cmdInsertNecesarCerereOferta.Parameters("@IDPiesaNecesar").Value = PieseNecesareOferta(i - 1).IDPiesaNecesar
cmdInsertNecesarCerereOferta.Parameters("@IDPiesaCerereOferta").Value = insertedIDPiesaCerereOferta
cmdInsertNecesarCerereOferta.ExecuteNonQuery()
salvat += 1
Me.tsspb_SalvareCerereOferta.Value = CInt(100 * salvat / cantTotalaPiese)
Next
End Select
Next
Next
sqlTrans.Commit()
MsgBox("Cererea de oferta a fost salvata.")
Catch ex As Exception
Try
sqlTrans.Rollback()
MsgBox("A aparut o eroare." + vbNewLine + ex.ToString + vbNewLine + "RollBack success. Cererea nu a fost salvata.")
Catch ex2 As SqlException
If Not sqlTrans.Connection Is Nothing Then
MsgBox("An exception of type " & ex2.GetType().ToString() & _
" was encountered while attempting to roll back the transaction.")
End If
End Try
Finally
If conn.State = ConnectionState.Open Then conn.Close()
End Try
Else
MsgBox("Nu ai completat integral cererea de oferta!")
End If
End Sub
query that locks: 查询锁定:
SELECT TOP (100) PERCENT dbo.qry_NecesareNerezolvate.IDPiesaNecesar, COUNT(dbo.NecesareCereriOferte.IDPiesaCerereOferta) AS CereriOferte,
dbo.qry_NecesareNerezolvate.IDNecesar, dbo.qry_NecesareNerezolvate.IDPiesaDeSchimb, dbo.qry_NecesareNerezolvate.Cantitate
FROM dbo.qry_NecesareNerezolvate LEFT OUTER JOIN
dbo.NecesareCereriOferte ON dbo.qry_NecesareNerezolvate.IDPiesaNecesar = dbo.NecesareCereriOferte.IDPiesaNecesar
GROUP BY dbo.qry_NecesareNerezolvate.IDPiesaNecesar, dbo.qry_NecesareNerezolvate.IDNecesar, dbo.qry_NecesareNerezolvate.IDPiesaDeSchimb,
dbo.qry_NecesareNerezolvate.Cantitate
qry_NecesareNerezolvate: qry_NecesareNerezolvate:
SELECT TOP (100) PERCENT dbo.Necesare.IDPiesaNecesar, dbo.Necesare.IDNecesar, dbo.Necesare.IDPiesaDeSchimb, dbo.Necesare.Cantitate, dbo.Necesare.UM,
dbo.Necesare.Observatii
FROM dbo.Necesare LEFT OUTER JOIN
dbo.qry_NecesareComandateRezolvate ON dbo.Necesare.IDPiesaNecesar = dbo.qry_NecesareComandateRezolvate.IDPiesaNecesar
WHERE (dbo.qry_NecesareComandateRezolvate.IDPiesaNecesar IS NULL)
qry_NecesareComandateRezolvate: qry_NecesareComandateRezolvate:
SELECT dbo.Necesare.IDPiesaNecesar, dbo.NecesareComenzi.IDPiesaComanda, dbo.NecesareRezolvate.IDBonTransfer
FROM dbo.Necesare LEFT OUTER JOIN
dbo.NecesareComenzi ON dbo.Necesare.IDPiesaNecesar = dbo.NecesareComenzi.IDPiesaNecesar LEFT OUTER JOIN
dbo.NecesareRezolvate ON dbo.Necesare.IDPiesaNecesar = dbo.NecesareRezolvate.IDPiesaNecesar
WHERE (dbo.NecesareComenzi.IDPiesaComanda IS NOT NULL) OR
(dbo.NecesareRezolvate.IDBonTransfer IS NOT NULL)
for i=1 : insert , select then insert is working 对于i = 1 : insert ,请选择,然后insert工作
then i=2 and: INSERT into table2... is working but SELECT FROM table1 and table3... gets timeout... 然后我= 2并且: 插入到表2中...正在工作,但是从表1和表3中进行选择...会超时...
I don't understand why! 我不明白为什么!
PS: If I break the code before second run of SELECT FROM table3 then go to SSMS and run the select query it gets timeout too... PS:如果我在第二次运行SELECT FROM table3之前破坏了代码,然后转到SSMS并运行select查询,它也会超时。
In your code sample below, you have the transaction open till the end of the For Loop. 在下面的代码示例中,您将打开事务直到For循环结束。 It seems to me that when i =1 , the transaction gets opened and a insertion is made.
在我看来,当i = 1时,交易被打开并进行插入。 Now when i=2 , the to be inserted row when i=1 is in uncomitted state and if your select is joining to the table1 the lock level would have escalated to table level and locked everything down.
现在,当i = 2时,当i = 1处于未提交状态时要插入的行,并且如果您的选择正在加入table1,则锁定级别将升级为表级别并锁定所有内容。 Move the commit to inside the for loop and check how it goes.
将提交移动到for循环中,并检查其进行方式。
for i=1 to x
...
INSERT into table2
...
SELECT FROM table3
...
INSERT into table3
...
next i
sqltransaction.commit
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.