2015-09-07 13 views
6

Sto usando jOOQ all'interno di un progetto esistente che utilizza anche un codice JDBC personalizzato. All'interno di un jOOQ transaction ho bisogno di chiamare qualche altro codice JDBC e ho bisogno di passare attraverso la connessione attiva in modo che tutto entri nella stessa transazione.Come ottenere la connessione sottostante all'interno di una transazione usando jOOQ?

Non so come recuperare la connessione sottostante all'interno di una transazione jOOQ.

create.transaction(configuration -> { 
    DSLContext ctx = DSL.using(configuration); 

    // standard jOOQ code 
    ctx.insertInto(...); 

    // now I need a Connection 
    Connection c = ctx.activeConnection(); // not real, this is what I need 
    someOtherCode(c, ...); 
}); 

Leggendo i documenti e sbirciare un po 'sul codice sorgente mia scommessa migliore è questa:

configuration.connectionProvider().acquire() 

Ma il nome è un po' fuorviante in questo particolare caso d'uso. Non voglio una nuova connessione, solo quella attuale. Penso che questa sia la strada da percorrere perché la configurazione è derivata e otterrò sempre la stessa connessione, ma non sono sicuro e non riesco a trovare la risposta nella documentazione.

risposta

2

L'API di jOOQ non fa presupposti sull'esistenza di una connessione "corrente". A seconda delle implementazioni concrete di ConnectionProvider, TransactionProvider, ecc., Ciò potrebbe essere possibile o meno.

La soluzione è generalmente buona, però. Basta fare in modo di seguire contratto SPI s' il ConnectionProvider:

Connection c = null; 
try { 
    c = configuration.connectionProvider().acquire(); 
    someOtherCode(c, ...); 
} 
finally { 
    configuration.connectionProvider().release(c); 
} 

È possibile che questo va bene quando si sta utilizzando di jOOQ DefaultTransactionProvider, per esempio.

Nota v'è una richiesta di funzionalità in attesa #4552 che vi permetterà di eseguire codice nel contesto di una ConnectionProvider e le sue chiamate a acquire() e release(). Ecco come sarà:

DSL.using(configuration) 
    .connection(c -> someOtherCode(c, ...)); 
+0

Grazie a @LukasEder per la tua risposta veloce. Sto usando 'DefaultTransactionProvider'. 'ConnectionProvider' è' DataSourceConnectionProvider' e no 'DefaultConnectionProvider'. Ho visto che il metodo 'ConnectionProvider.release()' non fa nulla in quest'ultimo e chiude la connessione nel primo. Il 'DefaultTransactionProvider' dice nei documenti che _intende funzionare con' DefaultConnectionProvider'_. Sono nei guai? ;-) Sembra che potrei uccidere la transazione troppo presto. – sargue

+1

@sargue: No, non sei nei guai. La 'Configurazione' locale è derivata dalla tua' Configurazione'. 'DefaultTransactionProvider' localmente usa un' DefaultConnectionProvider' e mantiene 'Connection' per l'ambito di una transazione. Sospetto che questo meriti più documentazione –

+0

Grazie a @LukasEder. Fatto un po 'di modifica della risposta e accettato come la migliore soluzione corrente. Forse un metodo sul fornitore di transazioni sarebbe utile? 'configuration.transactionProvider(). currentConnection()' che restituisce null sul 'NoTransactionProvider' o genera qualche eccezione su altri, più esotici, provider che non possono supportarlo. Posso creare un problema in GitHub se pensi che possa essere utile. – sargue