Menurut http://docs .oracle.com/javase/7/docs/api/java/sql/Connection.html#close() :
Tes ini, menggunakan Mysql daripada Oracle mengkonfirmasi fakta ini:
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();
}
}
}
Menurut http://tomcat.apache.org/tomcat-7.0 -doc/jdbc-pool.html :
Saya akan merekomendasikan untuk tidak menyetel removeAbandoned
sehingga Oracle menutup koneksi setelah batas waktu di sisi server, daripada menutupnya oleh Tomcat. Oracle mungkin tidak akan melakukan transaksi dalam kasus itu, tetapi Anda perlu menguji ini.
Atau, dapatkah Anda meningkatkan removeAbandonedTimeout
pengaturan, sehingga program Anda dapat selesai, dan tidak ada koneksi yang ditinggalkan?
Masalah lain yang Anda miliki adalah bahwa aplikasi Anda telah menjadi terikat dengan Oracle karena Anda mengandalkan implementasi driver di mana spesifikasi memiliki lubang di dalamnya. Jika Anda bisa, memprogram dengan spesifikasi, sehingga Anda bebas untuk memigrasikan aplikasi Anda ke database yang berbeda, meskipun saya tahu itu sulit dalam praktiknya.
Solusi yang sama sekali berbeda adalah dengan mengambil kumpulan koneksi sumber terbuka, dan memperluasnya dengan pencegat AOP yang dapat mencegat panggilan ke close
dan cari tahu apakah transaksi telah dilakukan, dan jika tidak, panggil rollback
pada sambungan. Itu solusi yang cukup rumit... :-)