Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 11
  1. #1
    Moderatore di CMS L'avatar di kalosjo
    Registrato dal
    Jul 2001
    residenza
    In culo alla luna
    Messaggi
    1,999

    [VB.NET] Transazioni

    Carissimi colleghi, gentili colleghe.

    Avrei un quesito da proporVi.

    Ho creato una classe che gestisce la connessione e tutte le operazioni su database.

    All'interno della classe gli oggetti Connection e Command sono dichiarati private, quindi visibili in tutta la classe.

    La connessione viene aperta e assegnata al command in uno dei metodi della classe.

    In un altro metodo, che si occupa di eseguire le query di comando (insert, update e delete) scrivo:

    codice:
    LocalCmd.CommandText = StrQ
    RecInteressati = LocalCmd.ExecutenonQuery()
    Esiste anche un metodo che apre una transazione e la assegna al command:

    codice:
    Trans = DbConn.BeginTransaction(System.Data.IsolationLevel.Serializable)
    LocalCmd.Transaction = Trans
    In una porzione di codice che utilizza questa classe apro prima la transazione (quindi viene eseguito il secondo codice) perchè devo eseguire una serie di query di comando, poi eseguo la prima (una insert), ma mi restituisce un errore:
    "Execute richiede che il comando abbia un oggetto Transaction quando la connessione assegnata al comando si trova in una transazione locale in sospeso. La proprietà Transaction del comando non è stata inizializzata".
    Il che vuol dire che l'oggetto command non ha una transazione assegnata. Ma la transazione viene assegnata porprio nella seconda porzione di codice che ho scritto.......

    Qualche dritta?

    Thanks
    Scusate i puntini di sospensione...... La verità è che non ho argomenti....

  2. #2
    Moderatore di CMS L'avatar di kalosjo
    Registrato dal
    Jul 2001
    residenza
    In culo alla luna
    Messaggi
    1,999
    :master:

    Nessuno che possa darmi un consiglio?

    :berto:
    Scusate i puntini di sospensione...... La verità è che non ho argomenti....

  3. #3
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Probabilmente sarebbe utile dare un'occhiata a tutto il codice della classe ...

  4. #4
    Moderatore di CMS L'avatar di kalosjo
    Registrato dal
    Jul 2001
    residenza
    In culo alla luna
    Messaggi
    1,999
    Ok, lo posto tutto.

    codice:
     
    Imports System.Data.SqlClient
    Public Class DbParser
        Private TDB As String
        Private PathDb As String
        Private ServerDb As String
        Private NomeDb As String
        Private UidDb As String
        Private PwdDb As String
        Private ODBCName As String
        Private DbConn As Object
        Private ConnString As String
        Private MessaggioErrore As String
        Private RecInteressati As Int64
        Private LocalDA As Object
        Private LocalDS As New DataSet
        Private LocalCmd As Object
        Private Trans As Object
    
        Public Property TipoDb() As String
            Get
                Return TDB
            End Get
            Set(ByVal NTipo As String)
                TDB = NTipo
            End Set
        End Property
    
        Public Property NomeODBC() As String
            Get
                Return ODBCName
            End Get
            Set(ByVal NODBC As String)
                ODBCName = NODBC
            End Set
        End Property
    
        Public Property FilePath() As String
            Get
                Return PathDb
            End Get
            Set(ByVal NPath As String)
                PathDb = NPath
            End Set
        End Property
    
        Public Property NomeServer() As String
            Get
                Return ServerDb
            End Get
            Set(ByVal NServer As String)
                ServerDb = NServer
            End Set
        End Property
    
        Public Property NomeDatabase() As String
            Get
                Return NomeDb
            End Get
            Set(ByVal NDb As String)
                NomeDb = NDb
            End Set
        End Property
    
        Public Property UseridAccesso() As String
            Get
                Return UidDb
            End Get
            Set(ByVal NUid As String)
                UidDb = NUid
            End Set
        End Property
    
        Public Property PwdAccesso() As String
            Get
                Return PwdDb
            End Get
            Set(ByVal NPwd As String)
                PwdDb = NPwd
            End Set
        End Property
    
        Public ReadOnly Property MsgErrore() As String
            Get
                Return MessaggioErrore
            End Get
        End Property
    
        Public ReadOnly Property RecordsInteressati() As Int64
            Get
                Return RecInteressati
            End Get
        End Property
    
        Public Function Connetti() As Boolean
    
            Try
                Select Case TDB
                    Case "0"    'ODBC
                        ConnString = ODBCName
                        DbConn = New Data.Odbc.OdbcConnection(ConnString)
                        LocalDA = New Data.Odbc.OdbcDataAdapter
                        LocalCmd = New Data.Odbc.OdbcCommand
                    Case "1"    'access
                        ConnString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + PathDb + ";User Id=admin;Password=" + PwdDb + ";"
                        DbConn = New Data.Oledb.OleDbConnection(ConnString)
                        LocalDA = New Data.OleDb.OleDbDataAdapter
                        LocalCmd = New Data.OleDb.OleDbCommand
                    Case "2"    'SqlServer
                        ConnString = "Provider=sqloledb;Data Source=" + ServerDb + ",1433;Network Library=DBMSSOCN;Initial Catalog=" + NomeDb + ";User ID=" + UidDb + ";Password=" + PwdDb + ";"
                        DbConn = New Data.SqlClient.SqlConnection(ConnString)
                        LocalDA = New Data.SqlClient.SqlDataAdapter
                        LocalCmd = New Data.SqlClient.SqlCommand
                    Case "3"    'MySQL ODBC 3.51
                        ConnString = "DRIVER={MySQL ODBC 3.51 Driver};SERVER=" + ServerDb + ";PORT=3306;DATABASE=" + NomeDb + "; USER=" + UidDb + ";PASSWORD=" + PwdDb + ";OPTION=3;"
                        DbConn = New Data.Odbc.OdbcConnection(ConnString)
                        LocalDA = New Data.Odbc.OdbcDataAdapter
                        LocalCmd = New Data.Odbc.OdbcCommand
                    Case "4"    'PostgreSQL
                        ConnString = "DRIVER={PostgreSQL Unicode};SERVER=" + ServerDb + ";port=5432;DATABASE=" + NomeDb + ";UID=" + UidDb + ";PWD=" + PwdDb + ";"
                        DbConn = New Data.Odbc.OdbcConnection(ConnString)
                        LocalDA = New Data.Odbc.OdbcDataAdapter
                        LocalCmd = New Data.Odbc.OdbcCommand
                End Select
                DbConn.Open()
                LocalCmd.Connection = DbConn
                Return True
            Catch ex As Exception
                MessaggioErrore = "Impossibile connettersi al DB." & ControlChars.CrLf & "Errore restituito: " & ex.Message
                Return False
            End Try
        End Function
    
        Public Function EseguiSQL(ByVal StrQ As String) As Boolean
            If StrQ = "" Then
                MessaggioErrore = "Stringa query non valida!"
                Return False
                Exit Function
            End If
            Try
                LocalCmd.CommandText = StrQ
                RecInteressati = LocalCmd.ExecutenonQuery()
                Return True
            Catch ex As Exception
                MessaggioErrore = "Errore nell'esecuzione del comando." & ControlChars.CrLf & "Errore restituito: " & ex.Message
                Return False
            End Try
        End Function
    
        Public Function Estrai(ByVal StrQ As String, ByRef ExtDS As DataSet, ByVal NomeTab As String, ByVal Reimposta As Boolean) As Boolean
            Dim ECmd As Object
            Try
                Select Case TDB
                    Case "0", "3", "4"
                        ECmd = New Data.Odbc.OdbcCommand(StrQ, DbConn)
                    Case "1"
                        ECmd = New Data.OleDb.OleDbCommand(StrQ, DbConn)
                    Case "2"
                        ECmd = New Data.SqlClient.SqlCommand(StrQ, DbConn)
                End Select
                LocalDA.selectcommand = ECmd
                If Reimposta Then
                    ExtDS = New DataSet("Elenco")
                    ExtDS.Clear()
                End If
                LocalDA.fill(ExtDS, NomeTab)
                Return True
            Catch ex As Exception
                MessaggioErrore = "Impossibile estrarre i dati." & ControlChars.CrLf & "Errore restituito: " & ex.Message
                Return False
            End Try
        End Function
    
        Public Function MaxPk(ByVal NomeTabella As String, ByVal NomeCampo As String) As Long
            Dim StrQ As String
            Dim LocDset As New DataSet
    
            StrQ = "select max(" & NomeCampo & ") as maxpk from " & NomeTabella
            If Estrai(StrQ, LocDset, "estrazione", True) Then
                If LocDset.Tables("esrazione").Rows(0).Item("maxpk") Is System.DBNull.Value Then
                    Return 1
                Else
                    Return LocDset.Tables("esrazione").Rows(0).Item("maxpk") + 1
                End If
            Else
                MsgBox(MessaggioErrore, MsgBoxStyle.Critical, "Errore in estrazione nuova Primary Key")
            End If
    
        End Function
    
        Public Sub BeginTrans()
    
            Trans = DbConn.BeginTransaction(System.Data.IsolationLevel.Serializable)
            LocalCmd.Transaction = Trans
    
        End Sub
    
        Public Sub RollBackTrans()
    
            Trans.RollBack()
    
        End Sub
    
        Public Sub CommitTrans()
    
            Trans.Commit()
    
        End Sub
    
    End Class
    Un po' lungo...
    Scusate i puntini di sospensione...... La verità è che non ho argomenti....

  5. #5
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Ok ... ma adesso che abbiamo tutto il codice da seguire, descrivi quello che fai indicando la sequenza di metodi chiamati e quando si verifica l'errore ...

  6. #6
    Moderatore di CMS L'avatar di kalosjo
    Registrato dal
    Jul 2001
    residenza
    In culo alla luna
    Messaggi
    1,999
    Va bene.

    Prima di richiamare la transazione eseguo un paio di query che estraggono dati (una semplice login).

    Funziona tutto.

    codice:
     
    strq="select bla bla bla"
    If DbConnection.Estrai(StrQ, LocDset, "utenti", True) Then
        If LocDset.Tables("utenti").Rows.Count = 0 Then
            bla
            bla
            bla 'niente a che fare con la classe
        end if
    end if
    
    DbConnection.BeginTrans()
    StrQ = "update bla bla bla"
    If Not DbConnection.EseguiSQL(StrQ) Then
        MsgBox("Errore: " & DbConnection.MsgErrore, MsgBoxStyle.Critical, "Accesso")
        DbConnection.RollBackTrans()
        Return
    End If
    Il messaggio che mi restituisce è proprio quello del primo post.....
    Scusate i puntini di sospensione...... La verità è che non ho argomenti....

  7. #7
    Moderatore di CMS L'avatar di kalosjo
    Registrato dal
    Jul 2001
    residenza
    In culo alla luna
    Messaggi
    1,999
    Cavolo, risolto!!!!

    Nel metodo estrai avevo dimenticato di scaricare il command locale ECmd (Ecmd.Dispose()) e quindi era quello che dava il problema..........

    Dovrei stare più attento..........
    Scusate i puntini di sospensione...... La verità è che non ho argomenti....

  8. #8
    Scusa ma con la classe che hai postato non puoi gestire query parametriche o sbaglio?
    Anche io utilizzo una classe simile ma, appunto, non so come potrei integrare la gestione dei parametri. Qaulche idea?

  9. #9
    Moderatore di Programmazione L'avatar di alka
    Registrato dal
    Oct 2001
    residenza
    Reggio Emilia
    Messaggi
    24,472
    A prima vista, il codice mi sembra molto "caotico": meno male che il problema è già stato risolto poiché, ad una prima occhiata, non mi sarebbe stato possibile ricostruire il "flusso" del programma e la sequenza con cui vengono eseguite le istruzioni.

    Anche io creo delle classi di utilità per la connessione al database (in .NET non è possibile fare altro se si vuole condividere una connessione ai dati... alla faccia del RAD, almeno copiare bene dai concorrenti, ma questo è un altro discorso), tuttavia ogni oggetto che deve essere chiuso o distrutto, deve subire questa sorte e ciò è molto difficile se si trasformano i riferimenti a Connection, Transaction e Command in campi/membri della classe. :master:
    MARCO BREVEGLIERI
    Software and Web Developer, Teacher and Consultant

    Home | Blog | Delphi Podcast | Twitch | Altro...

  10. #10
    Anche io creo delle classi di utilità per la connessione al database (in .NET non è possibile fare altro se si vuole condividere una connessione ai dati... alla faccia del RAD, almeno copiare bene dai concorrenti, ma questo è un altro discorso), tuttavia ogni oggetto che deve essere chiuso o distrutto, deve subire questa sorte e ciò è molto difficile se si trasformano i riferimenti a Connection, Transaction e Command in campi/membri della classe.
    Perdonami se risulto ripetitivo, ma come potrei gestire l'esecuzione di una query parametrica non conoscendo a priori(ovviamente) il numero di parametri?

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.