2016-04-16 15 views
1

Ich habe eine Methode, die eine Verbindung mit eingebetteter Derby-Datenbank erstellt und eine Select-Abfrage für sie ausführt. HierEine Verbindung kann nicht geschlossen werden, während eine Transaktion noch aktiv ist. Ausnahme bei connection.close()

public PersonMID findPersonMID(String personAlias, CodeUID aliasTypeCodeUID, LogicalDomainMID logicalDomainMID) throws SQLException 
{ 
    Connection connection = getConnection(); 

    try 
    { 
     QueryExecutor<Long> findPersonIdByPersonAliasExecutor = FindPersonIdByPersonAliasDelegate.getExecutor(authority,connection, personAlias); 

     Long result = findPersonIdByPersonAliasExecutor.execute(); 

     if(result == null) 
     { 
      return null; 
     } 
     return PersonMID.create(authority, result); 
    } 
    finally 
    { 
     JDBCAssistant.close(connection); 
    } 

ist das, was meine Frage wie folgt aussieht:

select P.PRSON_ID from PRSON_ALIAS PA join PRSON P on P.PRSON_ID = PA.PRSON_ID and P.LOGICAL_DOMAIN_ID = ? where PA.PRSON_ALIAS_TYPE_CD = ? and PA.ALIAS = ? 

Wenn ich durch diesen Code ausführen, erhalte ich eine Ausnahme JDBCException: java.sql.SQLException: Cannot close a connection while a transaction is still active.

Aber wenn ich Connection.commit() anrufen, bevor ich die Connection schließen oder Set autoCommittrue (es ist standardmäßig auf false für meine Connection eingestellt) für meine Connection, ist es mir erlaubt um die Verbindung erfolgreich zu schließen und das gewünschte Ergebnis zu erhalten.

Aber muss ich wirklich commit() für eine Select Operation aufrufen? Was gibt es zu begehen? Gibt es irgendwo eine Sperre, die nicht freigegeben wird, wenn ich mich nicht verpflichte? Diese post sagt, ich sollte es nicht tun müssen. Ich sollte in der Lage sein, meine Verbindung zu schließen, ohne ein Commit oder Rollback durchführen zu müssen.

Was fehlt mir?

+0

Was passiert, wenn Sie die automatische Commit-Modus mit Connection.setAutoCommit (true) zwingen geschieht? –

+0

@NicolasFilotto In diesem Fall kann ich die Verbindung ohne Fehler schließen. –

+0

Also ich vermute, dass irgendwo in der globalen Konfiguration von Derby, dies nicht mehr der automatische Commit-Modus, der standardmäßig aktiviert ist. Was liefert getAutoCommit() nach dem Erhalt der Verbindung? Oder gibt es etwas nicht falsches, wenn die Methode getConnection() –

Antwort

1

Wenn Sie nicht in autoCommit Modus sind, dann ist eine SELECT Aussage in der Tat Lesesperren halten, je nach Isolationsstufe, und so eine SELECT Abfrage zu begehen ist mehr als ein No-op.

Ja, es gibt keine Änderung an der Datenbank, aber die Festschreibung teilt der Datenbank-Engine immer mit, dass Ihre Transaktion die Daten überprüft hat, und kann daher anderen Transaktionen erlauben, die Daten zu ändern.

Hier einige Hintergrundmaterial:

  1. Isolationsstufen und Gleichzeitigkeit; https://db.apache.org/derby/docs/10.12/devguide/cdevconcepts15366.html
  2. Gemeinsame Sperren: https://db.apache.org/derby/docs/10.12/devguide/cdevconcepts842304.html