Enligt http://docs .oracle.com/javase/7/docs/api/java/sql/Connection.html#close() :
Detta test, med Mysql istället för Oracle bekräftar detta faktum:
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();
}
}
}
Enligt http://tomcat.apache.org/tomcat-7.0 -doc/jdbc-pool.html :
Jag skulle rekommendera att inte ställa in removeAbandoned
så att Oracle stänger anslutningen efter en timeout på serversidan, snarare än att Tomcat stänger den. Oracle kommer förmodligen inte att begå transaktionen i så fall, men du skulle behöva testa detta.
Alternativt kan du öka removeAbandonedTimeout
inställning, så att ditt program kan avslutas och inga anslutningar avbryts?
Ett annat problem du har är att din applikation har blivit knuten till Oracle eftersom du förlitar dig på drivrutinsimplementeringen där specen har ett hål i sig. Om du kan, programmera mot specifikationer, så att du är fri att migrera din applikation till en annan databas, även om jag vet att det är svårt i praktiken.
En helt annan lösning skulle vara att ta en anslutningspool med öppen källkod och utöka den med en AOP-interceptor som kan avlyssna samtal till close
och räkna ut om transaktionen har genomförts, och om inte, ring rollback
på anslutningen. Det är dock en ganska komplicerad lösning... :-)