ADO.NET事务无法正常工作

时间:2013-03-26 16:16:23

标签: vb.net ado.net transactions dataset executenonquery

嗨,我对ADO.net中的交易感到生气,

我想做什么:我的数据集中的所有更改,使用Update方法执行,在事务中执行 - 这很好,但是我需要通过SQL查询执行其他sql命令仍然是一个事务。我的代码是按照良好的提示编写的,如果任何命令失败,则try-catch阻止我回滚整个事务,如果正确的错误提交更改,则 - >这恰好适用于通过Update方法执行的命令,因为当我通过executeNonQuery执行时,当我观察数据库中的更改时立即进行更改...根据所有指导我看到了两种方法如何在数据集内和executeNonQuery中使用事务命令,但没有发现它们的任何组合或这种方法的任何问题,任何想法?

严重的整个代码不是英文的,并且很长,事务经历了几次更新,没关系,我希望我们得到问题的核心......这里是代码:

'这是应该在一个事务中完成所有表的整个更新,插入和删除的主要方法

Public Sub DSdoDBOtazkyAdotaznikINSERT_UPDATE_DELETE()
    'vytvoření zálohy 
    Zaloha.vytvorZalohu(My.Settings.RecentDatabasedUsed, False, True)

    Try
      'Priprava Transakce
      SpojeniS_DB_TRANSAKCNI.Open()
    Catch ex As Exception
      Throw ex
      Exit Sub
    End Try

    Dim QtionAQnnaireTransaction As System.Data.OleDb.OleDbTransaction

    QtionAQnnaireTransaction = Me.SpojeniS_DB_TRANSAKCNI.BeginTransaction(IsolationLevel.ReadCommitted)

    '1, Update Commandy
    QstionUpdateCommand.Transaction = QtionAQnnaireTransaction
    CategoryUpdateCommand.Transaction = QtionAQnnaireTransaction
    CategoryDefUpdateCommand.Transaction = QtionAQnnaireTransaction
    CCheckUpdateCommand.Transaction = QtionAQnnaireTransaction
    BatteryItemUpdateCommand.Transaction = QtionAQnnaireTransaction
    ChecKUpdateCommand.Transaction = QtionAQnnaireTransaction
    TextFillUpdateCommand.Transaction = QtionAQnnaireTransaction
    RowUpdateCommand.Transaction = QtionAQnnaireTransaction
    ProgramCodeupdateCommand.Transaction = QtionAQnnaireTransaction
    DotaznikyVsechnyUpdateCommand.Transaction = QtionAQnnaireTransaction
    '2, Insert Commandy
    QstionInsertCommand.Transaction = QtionAQnnaireTransaction
    CategoryInsertCommand.Transaction = QtionAQnnaireTransaction
    CategoryDefInsertCommand.Transaction = QtionAQnnaireTransaction
    CCheckInsertCommand.Transaction = QtionAQnnaireTransaction
    BatteryItemInsertCommand.Transaction = QtionAQnnaireTransaction
    ChecKInsertCommand.Transaction = QtionAQnnaireTransaction
    TextFillInsertCommand.Transaction = QtionAQnnaireTransaction
    RowInsertCommand.Transaction = QtionAQnnaireTransaction
    ProgramCodeInsertCommand.Transaction = QtionAQnnaireTransaction
    DotaznikVsechnyInsertCommand.Transaction = QtionAQnnaireTransaction
    '3, Delete Commandy
    QstionDeleteCommand.Transaction = QtionAQnnaireTransaction
    DotaznikVsechDeleteCommand.Transaction = QtionAQnnaireTransaction
    'ostatní DELETE commandy přiřazení do transakcí nalezneme v metodě DBpripravDatatableNaZapisDatS_PosunutimPK

    'CategoryDeleteCommand.Transaction = QtionAQnnaireTransaction
    'CategoryDefDeleteCommand.Transaction = QtionAQnnaireTransaction
    'CCheckDeleteCommand.Transaction = QtionAQnnaireTransaction
    'BatteryItemDeleteCommand.Transaction = QtionAQnnaireTransaction
    'ChecKDeleteCommand.Transaction = QtionAQnnaireTransaction
    'TextFillDeleteCommand.Transaction = QtionAQnnaireTransaction
    'RowDeleteCommand.Transaction = QtionAQnnaireTransaction
    'ProgramCodeDeleteCommand.Transaction = QtionAQnnaireTransaction

    Dim slovnikProPrvotniUpdate As New Dictionary(Of DataRow, Double)
    Try

      'nastaveni spojeni vsem commandum spojeni 
      Me.nastaveniPripojeniNaUDIprikazy(Me.SpojeniS_DB_TRANSAKCNI)

      '1, QUESTION
      '!!!!! důležitá záloha datasetu
      zalohujDataset()



      'DELETE otázek
      DATAdapter.DeleteCommand = QstionDeleteCommand


      DATAdapter.Update(DStabulkaOtazek.Select("MotherQReference is NOT NULL", Nothing, DataViewRowState.Deleted))

      DATAdapter.Update(DStabulkaOtazek.Select("MotherQReference is NULL", Nothing, DataViewRowState.Deleted))


      'UPDATE otázek

      'potřeba řešit pořadí UPDATOVANÝCH OTÁZEK - problémová situace: pokud dojde k změbě pořadí otázky - tedy PK otázky se uvolní a posléze PK nové otázky nebo jiné updatované otázky bude nastaven na PK předešlé otázky, která již PK nemá - 
      'druhým problémem je pokud si dvě otázky "vymění PK", proto nejprve všem UPDATOVANÝM otázkám změníme UPDATOVANÝ PK na temporární - insertu uvolníme místo vložení a updatované otázky se zbaví zabraných

      DATAdapter.UpdateCommand = QstionUpdateCommand


      slovnikProPrvotniUpdate = DStabulkaOtazek.PRIPRAVAUPDATEzmenaPoradiaPKproUPDATE()

      'exekuce řádků pro nastavení Temporárních změn Update

      'hlavní otázka UPDATE - musí jít první kvůli kaskádě
      DATAdapter.Update(slovnikProPrvotniUpdate.Keys.Cast(Of DataRow).Where(Function(x) IsDBNull(x.Item("MotherQReference"))).ToArray)

      'podotázek otázka UPDATE - musí jít první kvůli kaskádě
      DATAdapter.Update(slovnikProPrvotniUpdate.Keys.Cast(Of DataRow).Where(Function(x) Not IsDBNull(x.Item("MotherQReference"))).ToArray)



      'InsertCommandProQuestion
      DATAdapter.InsertCommand = QstionInsertCommand
      DATAdapter.Update(DStabulkaOtazek.Select(Nothing, Nothing, DataViewRowState.Added))




      'vrácení původních řádků - již zpětně změny
      DStabulkaOtazek.UNDOakceNaUpdate(slovnikProPrvotniUpdate)

      'hlavní otázka UPDATE - musí jít první kvůli kaskádě
      DATAdapter.Update(slovnikProPrvotniUpdate.Keys.Cast(Of DataRow).Where(Function(x) IsDBNull(x.Item("MotherQReference"))).ToArray)

      'podotázek otázka UPDATE - musí jít první kvůli kaskádě
      DATAdapter.Update(slovnikProPrvotniUpdate.Keys.Cast(Of DataRow).Where(Function(x) Not IsDBNull(x.Item("MotherQReference"))).ToArray)

      '2, BATTERYITEM
      Me.DBpripravDatatableNaZapisDatS_PosunutimPK(DStabulkaBaterii, QtionAQnnaireTransaction)


      'InsertCommand pro BatteryItem
      DATAdapter.InsertCommand = BatteryItemInsertCommand
      'UpdateCommand pro BatteryItem
      DATAdapter.UpdateCommand = BatteryItemUpdateCommand
      'Execute Commandu pro BatteryItem
      DATAdapter.Update(DSaplikace.Tables.Item("BatteryItem"))


      '3, CATEGORY
      Me.DBpripravDatatableNaZapisDatS_PosunutimPK(DStabulkaKategorii, QtionAQnnaireTransaction)

      'InsertCommand pro CATEGORY
      DATAdapter.InsertCommand = CategoryInsertCommand
      'UpdateCommand pro CATEGORY
      DATAdapter.UpdateCommand = CategoryUpdateCommand
      'Execute Commandu pro CATEGORY



      DATAdapter.Update(DSaplikace.Tables.Item("CATEGORY"))


      '4, PROGRAMCODE
      Me.DBpripravDatatableNaZapisDatS_PosunutimPK(DSaplikace.Tables.Item("ProgramCode"), QtionAQnnaireTransaction)

      'InsertCommand pro ProgramCode
      DATAdapter.InsertCommand = ProgramCodeInsertCommand
      'UpdateCommand pro ProgramCode
      DATAdapter.UpdateCommand = ProgramCodeupdateCommand
      'DeleteCommand pro ProgramCode
      DATAdapter.Update(DSaplikace.Tables.Item("ProgramCode"))

      '5, ROW
      Me.DBpripravDatatableNaZapisDatS_PosunutimPK(DStabulkaRadkyTababulky, QtionAQnnaireTransaction)
      'InsertCommand pro row
      DATAdapter.InsertCommand = RowInsertCommand
      'UpdateCommand pro row
      DATAdapter.UpdateCommand = RowUpdateCommand

      DATAdapter.Update(DSaplikace.Tables.Item("row"))

      '6, TEXTFILL
      Me.DBpripravDatatableNaZapisDatS_PosunutimPK(DStabulkaDynText, QtionAQnnaireTransaction)
      'InsertCommand pro textfill
      DATAdapter.InsertCommand = TextFillInsertCommand
      'UpdateCommand pro textfill
      DATAdapter.UpdateCommand = TextFillUpdateCommand
      'DeleteCommand pro textfill
      DATAdapter.Update(DSaplikace.Tables.Item("textfill"))

      '7, CHECK

      Me.DBpripravDatatableNaZapisDatS_PosunutimPK(DStabulkaKontrol, QtionAQnnaireTransaction)
      'InsertCommand pro CHECK
      DATAdapter.InsertCommand = ChecKInsertCommand
      'UpdateCommand pro CHECK
      DATAdapter.UpdateCommand = ChecKUpdateCommand

      DATAdapter.Update(DSaplikace.Tables.Item("CHECK"))



      '8, CategoryDefinition definition

      '  Me.DBpripravDatatableNaZapisDatS_PosunutimPK(DStabulkaDefinicKategorii, QtionAQnnaireTransaction, Me.SpojeniS_DB)
      'InsertCommand pro CategoryDefinition
      DATAdapter.InsertCommand = CategoryDefInsertCommand
      'UpdateCommand pro CategoryDefinition
      '  DATAdapter.UpdateCommand = CategoryDefUpdateCommand

      DATAdapter.Update(DSaplikace.Tables.Item("CategoryDef"))


      '10, Questionnaire - Update

      DotaznikyVsechnyUpdateCommand.Connection = SpojeniS_DB_TRANSAKCNI
      DotaznikVsechDeleteCommand.Connection = SpojeniS_DB_TRANSAKCNI
      DotaznikVsechnyInsertCommand.Connection = SpojeniS_DB_TRANSAKCNI

      DATAdapter.UpdateCommand = DotaznikyVsechnyUpdateCommand
      DATAdapter.Update(DSaplikace.Tables.Item("Questionnaire"))

      QtionAQnnaireTransaction.Commit()


    Catch ex As Exception

      undoDatDatasetu()
      QtionAQnnaireTransaction.Rollback()
      Throw ex
    Finally
      SpojeniS_DB_TRANSAKCNI.Close()
    End Try
  End Sub

这个方法应该有executeNoQuery - 在事务中删除命令,从上面的方法调用几次,因为我运行语句executeNonQuery(但应该在事务中),数据库接受更改

    Private Sub DBpripravDatatableNaZapisDatS_PosunutimPK(ByVal DT As DTCapi, ByVal transakce As OleDb.OleDbTransaction)
        'smažeme všechny řádky kontrol v DB k jedné otázce, pokud
        'došlo k Insertu nebo k Deletu alespoň jedné kontroly
        Dim HashSetPKotazekKontrolnaSmazani As New HashSet(Of String)
        Dim dtv As New DataView(DT)
        dtv.RowStateFilter = DataViewRowState.Added + DataViewRowState.Deleted


        For Each drv As DataRowView In dtv
          HashSetPKotazekKontrolnaSmazani.Add(drv("IDQnnaireQOrderQOrderMother"))
        Next

        'smazání řádků v DB
        For Each PKotazky As String In HashSetPKotazekKontrolnaSmazani
          Dim deleteCMD As New OleDb.OleDbCommand("DELETE FROM [" + DT.TableName + "] where IDQnnaireQOrderQOrderMother= ?")
          'nastavení parametru
          Dim parametrProSmazani As New OleDbParameter
          parametrProSmazani.Value = PKotazky

    ' HERE IS DELETE within transaction

          deleteCMD.Transaction = transakce
          deleteCMD.Connection = transakce.Connection
          deleteCMD.Parameters.Add(parametrProSmazani)

 'when following statement i call this changes in DB are done, no matter in didnt commited...transaction

          deleteCMD.ExecuteNonQuery()
        Next

        'odstranění z DT delete řádků
        Dim radkyNaSmazani As DataRow() = DT.Select(DataViewRowState.Deleted)
        For Each radek As DataRow In radkyNaSmazani
          DT.Rows.Remove(radek)
        Next
        'u všech řádků otázek, jejiž kontroly jsme vymazali v DB nastavíme v DT stav added
        Dim vyberovyRetezec As String = CDfunkce.ADOdtSelectRETEZECor("IDQnnaireQOrderQOrderMother", HashSetPKotazekKontrolnaSmazani)

        If vyberovyRetezec <> "" Then
          Dim radkyProOznaceniJakoPridane As DataRow() = DT.Select(vyberovyRetezec)
          'nastavení řádků Added
          For Each radek As DataRow In radkyProOznaceniJakoPridane
            If radek.RowState <> DataRowState.Added Then
              radek.AcceptChanges()
              radek.SetAdded()
            End If
          Next
        End If


      End Sub

0 个答案:

没有答案