0

我有以下问题:在 vb.net 中的一个 sqltransaction 中,我将数据插入到多个表中。
它是这样的:

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

锁定的查询:

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:

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

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)

对于i=1insertselect然后insert正在工作,
然后i=2并且:INSERT into table2...正在工作,但SELECT FROM table1 和 table3...超时...

我不明白为什么!PS:如果我在第二次运行SELECT FROM table3
之前破坏了代码,然后转到 SSMS 并运行选择查询,它也会超时......

4

1 回答 1

0

在下面的代码示例中,事务一直打开到 For 循环结束。在我看来,当 i =1 时,事务被打开并插入。现在,当 i=2 时,当 i=1 处于未提交状态时要插入的行,如果您的选择正在加入 table1,则锁定级别将升级到表级别并锁定所有内容。将提交移到 for 循环内部并检查它是如何进行的。

for i=1 to x
    ...
    INSERT into table2
    ...
    SELECT FROM table3
    ...
    INSERT into table3
    ...
next i
sqltransaction.commit
于 2013-08-02T05:42:28.793 回答