异常:Operation not allowed after ResultSet closed
这个异常感觉很莫名其妙,明明就在方法调用完就close啦,方法开始就开启ResultSet啦。为什么会报这个异常呢?
这个是怎么一回事呢,我先说一下,其实就是异步引起的,当你的项目有多个请求到同一个方法里面,可能就会遇到这里问题,而我是在反射的时候多个请求调用了这个反射而我的ResultSet 是放在方法外面作为全局变量,该类里面的方法都使用了这几个全局变量,当被请求多次,或者说调用多次,就会导致前面的方法还没有执行完关闭了ResultSet ,后面的又继续使用,但前面的方法已经关闭了,所以导致了ResultSet 异常。在方法执行时进行同步,或者让他们排队使用ResultSet ;说到底就是ResultSet 设置为全局变量引起这个异常;
第一:在页面js写取消异步 $.ajaxSettings.async = false;
第二:先private static final ReentrantLock lock=new ReentrantLock(); 然后在代码运行前加 lock.lock(); 它的意思是加锁,锁住这部分代码,不让别人去执行这部分代码;但是必须要解锁,在代码运行完的地方写 lock.unlock(); 表示解锁,让别人可以运行这部分代码或者说让其他请求执行这部分代码;如果不解锁是没有反应的谨记!!!
第三:synchronized(JdbcHelper.class){} 可以直接把方法写在里面;
synchronized 它不需要用户自己进行解锁,比较lock 来说是比较方便简洁的;他们可以同时使用,也可以多次使用;如在同一段代码块中,我用了synchronized 也可以再次使用synchronized;也可以在synchronized代码块中使用 lock;
方法1: $.ajaxSettings.async = false; 在要同步代码前加;
方法2:private static final ReentrantLock lock=new ReentrantLock(); //声明
public static <T>T getSingleResult(ResultSet rs, Class<T> obj) {
lock.lock();//加锁
private Connection conn = null;
private PreparedStatement ps = null;
private ResultSet rs = null;//把它放进同步锁里面方法体;
lock.unlock();//解锁
}
方法3:
public class JdbcHelper {
public static <T>T getSingleResult(ResultSet rs, Class<T> obj) {
synchronized(JdbcHelper.class){
private Connection conn = null;
private PreparedStatement ps = null;
private ResultSet rs = null;//把它放进同步锁里面方法体;
}
}
}
第四种:
就是在方法里面声明ResultSet,供方法本身使用,这样就不会发生混乱,如:
public List<KeHuHeTongVO> selectCustomerContract(int startIndex,
int pageSize, String condition) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
List<KeHuHeTongVO> list = new ArrayList<KeHuHeTongVO>();
try {
conn = DBUtil.getConnection();
ps = conn.prepareStatement(selectCustomerContract+condition+" LIMIT ?,?;");
ps.setInt(1, startIndex);
ps.setInt(2, pageSize);
rs = ps.executeQuery();
try {
list = JdbcHelper.getResult(rs, KeHuHeTongVO.class);
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
DBUtil.close(conn, ps, rs);
}
return list;
}
直接用第四种就可以解决这个问题了;
一般多次调用的方法或者封装类都会出现这个问题;