Volgens http://docs .oracle.com/javase/7/docs/api/java/sql/Connection.html#close() :
Deze test, waarbij Mysql wordt gebruikt in plaats van Oracle, bevestigt dit feit:
import static org.junit.Assert.assertEquals;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.junit.Test;
public class DBTest {
public Connection openConnection() throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver");
Connection c = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "password");
c.setAutoCommit(false);
return c;
}
@Test
public void testSO25886466() throws SQLException, ClassNotFoundException {
{
Connection c = openConnection();
PreparedStatement delete = c.prepareStatement("delete from temp");
delete.executeUpdate();
c.commit();
c.close();
}
{
Connection c = openConnection();
PreparedStatement insert = c.prepareStatement("insert into temp values ('a', 'b')");
insert.execute();
//c.commit(); as the op says, DONT commit!!
c.close(); //WITHOUT having closed the statement or committing the transaction!!
}
{
Connection c = openConnection();
PreparedStatement select = c.prepareStatement("select count(*) from temp");
select.execute();
ResultSet rs = select.getResultSet();
while(rs.next()){
assertEquals(0/*i'd expect zero here!*/, rs.getInt(1));
}
rs.close();
select.close();
c.close();
}
}
}
Volgens http://tomcat.apache.org/tomcat-7.0 -doc/jdbc-pool.html :
Ik zou aanraden om removeAbandoned
niet in te stellen zodat Oracle de verbinding sluit na een time-out aan de serverzijde, in plaats van dat Tomcat deze sluit. Oracle zal de transactie in dat geval waarschijnlijk niet uitvoeren, maar u zou dit moeten testen.
Als alternatief kunt u de removeAbandonedTimeout
. verhogen instelling, zodat uw programma kan worden voltooid en er geen verbindingen worden verbroken?
Een ander probleem dat u heeft, is dat uw toepassing aan Oracle is gebonden omdat u vertrouwt op de implementatie van het stuurprogramma waar de specificatie een gat in heeft. Als je kunt, programmeer dan tegen de specificaties, zodat je vrij bent om je applicatie naar een andere database te migreren, hoewel ik weet dat dat in de praktijk moeilijk is.
Een heel andere oplossing zou zijn om een open source-verbindingspool te nemen en deze uit te breiden met een AOP-interceptor die oproepen kan onderscheppen om te close
en bereken of de transactie is uitgevoerd, en zo niet, bel rollback
op de verbinding. Dat is wel een vrij complexe oplossing... :-)