/** * Register an object. Before calling this method, pollUnclosed() should be * called in a loop to remove old references. * * @param o the object * @param closeable the object to close * @param stackTrace whether the stack trace should be registered (this is * relatively slow) * @return the close watcher */ public static CloseWatcher register(Object o, Closeable closeable, boolean stackTrace) { ReferenceQueue<Object> q = queue; if (q == null) { q = new ReferenceQueue<Object>(); queue = q; } CloseWatcher cw = new CloseWatcher(o, q, closeable); if (stackTrace) { Exception e = new Exception("Open Stack Trace"); StringWriter s = new StringWriter(); e.printStackTrace(new PrintWriter(s)); cw.openStackTrace = s.toString(); } if (refs == null) { refs = createSet(); } refs.add(cw); return cw; }
private void closeOld() { while (true) { CloseWatcher w = CloseWatcher.pollUnclosed(); if (w == null) { break; } try { w.getCloseable().close(); } catch (Exception e) { trace.error(e, "closing session"); } // there was an unclosed object - // keep the stack trace from now on keepOpenStackTrace = true; String s = w.getOpenStackTrace(); Exception ex = DbException.get(ErrorCode.TRACE_CONNECTION_NOT_CLOSED); trace.error(ex, s); } }
return; CloseWatcher.unregister(watcher); session.cancel(); if (executingStatement != null) {
public JdbcConnection(ConnectionInfo ci) throws SQLException { try { // this will return an embedded or server connection session = ci.createSession().connect(); trace = session.getTrace(); int id = getNextTraceId(TraceObject.CONNECTION); setTrace(trace, TraceObject.CONNECTION, id); user = ci.getUserName(); url = ci.getURL(); // 不含参数 if (isInfoEnabled()) { String code = String.format("Connection %s = DriverManager.getConnection(%s, %s, \"\");", getTraceObjectName(), quote(url), quote(user)); trace.infoCode(code); } closeOld(); watcher = CloseWatcher.register(this, session, keepOpenStackTrace); } catch (Exception e) { throw logAndConvert(e); } }