根据
http://docs.oracle.com/javase/7/docs/api/java/sql/Connection.html#close():
引用:
“强烈建议应用程序在调用关闭方法之前显式提交或回滚活动事务。如果调用关闭方法并存在活动事务,则结果是实现定义的。”
使用Mysql而不是Oracle进行的此测试证实了这一事实:
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.close();
}
{
Connection c = openConnection();
PreparedStatement select = c.prepareStatement("select count(*) from temp");
select.execute();
ResultSet rs = select.getResultSet();
while(rs.next()){
assertEquals(0, rs.getInt(1));
}
rs.close();
select.close();
c.close();
}
}
}
根据
http://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html:
(boolean) Flag to remove abandoned connections if they exceed the removeAbandonedTimeout. If set to true a connection is considered abandoned and eligible for removal 如果它的使用时间超过了removeAbandonedTimeout,则将其视为已被遗弃并可进行删除。如果设置为true,可以从未关闭连接的应用程序中恢复db连接。另请参阅logAbandoned,默认值为false。
我建议不要设置removeAbandoned,而是让Oracle在服务器端超时后关闭连接,而不是Tomcat关闭连接。在这种情况下,Oracle可能不会提交事务,但您需要进行测试。
或者,您可以增加removeAbandonedTimeout设置的值,以便您的程序可以完成,没有连接被遗弃。
你面临的另一个问题是,你的应用程序已经与Oracle绑定在一起,因为你依赖于驱动程序实现,而规范中存在漏洞。如果可能的话,应该按照规范进行编程,这样你就可以自由地将应用程序迁移到不同的数据库,尽管我知道这在实践中很难。
完全不同的解决方案是,使用开源连接池,并使用AOP拦截器扩展它,以便可以拦截对close的调用,并确定是否已提交事务,如果没有,则在连接上调用rollback。不过这是一个相当复杂的解决方案... :-)
defaultAutoCommit=false
后,问题仍未得到解决...... - Deepak Bhatia