2013-06-03 13 views
7

Mentre la mia ipotesi può sembrare soggettiva, dopo alcune ricerche, ho scoperto che non è raro trovare sviluppatori che preferiscono un dummy Try/Catch invece di utilizzare l'elaborazione IDbConnection/IDbTransaction (Chiudi/Esci/Ripristina).Utilizzo sicuro per IDbConnection/IDbTransaction?

Ciò vale anche per alcuni degli sviluppatori più esperti e alcuni nuovi. Non farò intenzionalmente riferimento a nessuna delle domande su StackOverflow o collegamenti ai forum come esempio, quindi le persone non si offendono. Da what I found, la dichiarazione Using è safe to use (nessun gioco di parole previsto).

C'è qualcosa di sbagliato in questo? Si consideri il seguente codice:

Public Sub Commit() 
    Dim cn As IDbConnection = {CREATE_CONNECTION} 
    Dim tran As IDbTransaction = Nothing 

    cn.Open() 
    Try 
    tran = cn.BeginTransaction 
    'run some queries here 
    tran.Commit() 
    Catch ex As Exception 
    If Not tran Is Nothing Then tran.Rollback() 
    Throw 
    Finally 
    cn.Close() 
    End Try 
End Function 

Assumere {CREATE_CONNECTION} è segnaposto per un Sub che crea una connessione, a seconda del fornitore del database, scritta secondo tutte le possibili buone pratiche e non ha bisogno di ulteriori miglioramenti.

C'è un motivo per cui il codice di cui sopra non può essere riscritta come tale:

Using cn As IDbConnection = {CREATE_CONNECTION} 
    cn.Open() 
    Using tran As IDbTransaction = cn.BeginTransaction 
    'run some queries here 
    tran.Commit() 
    End Using 
End Using 

?

Chiaramente, la versione 2 è più intuitiva per quello che sta facendo. Ma forse mi manca qualcosa di importante qui? Cose come implementazioni specifiche del fornitore di librerie di accesso ai dati, che non chiamano Transaction.Commit e/o Connection.Close su Dispose internamente? Questo approccio è in fase di dismissione nel prossimo futuro o non è considerato come sufficientemente chiaro nel nella programmazione moderna/best practice? Strumenti di sviluppo di app mono/mobile che non supportano il debug per la parola chiave Using?

Sto cercando qualsiasi tipo di risposta per supportare o negare il punto. Preferibilmente quello con citazioni alla documentazione originale, qualcosa come Do not use Using with IDbTransaction when .... Anche i link ai blog o all'esperienza personale vanno bene.

risposta

14

Sono completamente con voi sulla connessione; che dovrebbe essere using e non è necessario l'esplicito Close(). La transazione è un po 'più complicata; il codice visualizzato è sicuramente eccessivo, ma non è del tutto definito che lo Dispose() debba eseguire un rollback. In realtà, quello è ciò che tende ad accadere in ogni implementazione che ho visto, ma è leggermente fastidioso che anche lo DbTransaction (che la maggior parte dei provider usa) in realtà non lo faccia. Contrasto a TransactionScope dove è esplicitamente definito che un Dispose() senza un commit conta come un rollback. A causa di ciò, io tendo da usare (scusate il C#):

using(var conn = GetOpenConnection()) 
using(var tran = conn.BeginTransaction()) { 
    try { 
     // TODO: do work 
     tran.Commit(); 
    } catch { 
     tran.Rollback(); 
     throw; 
    } 
} 

che è da qualche parte tra i due in termini di complessità. Non si scherza con lo null -checks, almeno.

+0

Questo spiega, grazie. Decisamente più chiaro della mia versione n. Anche +1 per 'GetOpenConnection', stavo anche inclinando a incorporare' cn.Open() 'in alcuni' CreateAndOpenConnection', in quanto sembra ridondante chiamare ogni volta. – Neolisk

+0

Se la connessione al database è chiusa, la transazione verrà ancora ripristinata? Capisco che sei più preoccupato per il possibile blocco. –

11

Quello che stai vedendo è la codifica degli sviluppatori secondo la documentazione (una "buona cosa"). La classe di base DbTransaction (utilizzata per la maggior parte delle implementazioni di transazione dei provider di dati) indica chiaramente in its documentation:

Dispose deve eseguire il rollback della transazione.Tuttavia, il comportamento di Dispose è specifico del provider e non dovrebbe sostituire il richiamo del rollback.

+3

buona presa sulla documentazione –

+0

+1. Grazie per aver trovato una nota ufficiale al riguardo. – Neolisk

+1

Grazie. MS dovrebbe sicuramente rendere più chiaro l'interfaccia reale. –