Ejemplo n.º 1
0
 private void closeSession() {
   if (session != null) {
     RuntimeException closeError = null;
     try {
       Command rollback = session.prepareLocal("ROLLBACK");
       rollback.executeUpdate();
     } catch (RuntimeException e) {
       closeError = e;
       server.traceError(e);
     } catch (Exception e) {
       server.traceError(e);
     }
     try {
       session.close();
       server.removeConnection(threadId);
     } catch (RuntimeException e) {
       if (closeError == null) {
         closeError = e;
         server.traceError(e);
       }
     } catch (Exception e) {
       server.traceError(e);
     } finally {
       session = null;
     }
     if (closeError != null) {
       throw closeError;
     }
   }
 }
Ejemplo n.º 2
0
 // 总共18条命令,这里包含16条
 // 下面这两条在run方法中特殊处理
 // SESSION_CANCEL_STATEMENT
 // SESSION_CHECK_KEY
 // 分三种级别,从大到小: SESSION级、COMMAND级、RESULT级
 private void process() throws IOException {
   int operation = transfer.readInt();
   switch (operation) {
     case SessionRemote.SESSION_PREPARE_READ_PARAMS:
     case SessionRemote.SESSION_PREPARE:
       {
         int id = transfer.readInt();
         String sql = transfer.readString();
         int old = session.getModificationId();
         Command command = session.prepareLocal(sql);
         boolean readonly = command.isReadOnly();
         cache.addObject(id, command);
         boolean isQuery = command.isQuery();
         ArrayList<? extends ParameterInterface> params = command.getParameters();
         transfer
             .writeInt(getState(old))
             .writeBoolean(isQuery)
             .writeBoolean(readonly)
             .writeInt(params.size());
         if (operation == SessionRemote.SESSION_PREPARE_READ_PARAMS) {
           for (ParameterInterface p : params) {
             ParameterRemote.writeMetaData(transfer, p);
           }
         }
         transfer.flush();
         break;
       }
     case SessionRemote.SESSION_CLOSE:
       {
         stop = true;
         closeSession();
         transfer.writeInt(SessionRemote.STATUS_OK).flush();
         close();
         break;
       }
     case SessionRemote.COMMAND_COMMIT:
       {
         // 并不是通过org.h2.jdbc.JdbcConnection.commit()触发,此方法是通过发送COMMIT SQL触发
         // 触发SessionRemote.COMMAND_COMMIT的是在集群环境下,通过org.h2.engine.SessionRemote.autoCommitIfCluster()触发
         if (commit == null) {
           commit = session.prepareLocal("COMMIT");
         }
         int old = session.getModificationId();
         commit.executeUpdate();
         transfer.writeInt(getState(old)).flush();
         break;
       }
     case SessionRemote.COMMAND_GET_META_DATA:
       {
         int id = transfer.readInt();
         int objectId = transfer.readInt();
         Command command = (Command) cache.getObject(id, false);
         ResultInterface result = command.getMetaData();
         cache.addObject(objectId, result);
         int columnCount = result.getVisibleColumnCount();
         transfer.writeInt(SessionRemote.STATUS_OK).writeInt(columnCount).writeInt(0);
         for (int i = 0; i < columnCount; i++) {
           ResultColumn.writeColumn(transfer, result, i);
         }
         transfer.flush();
         break;
       }
     case SessionRemote.COMMAND_EXECUTE_QUERY:
       {
         int id = transfer.readInt();
         int objectId = transfer.readInt();
         int maxRows = transfer.readInt();
         int fetchSize = transfer.readInt();
         Command command = (Command) cache.getObject(id, false);
         setParameters(command);
         int old = session.getModificationId();
         ResultInterface result;
         synchronized (session) {
           result = command.executeQuery(maxRows, false);
         }
         cache.addObject(objectId, result);
         int columnCount = result.getVisibleColumnCount();
         int state = getState(old);
         transfer.writeInt(state).writeInt(columnCount);
         int rowCount = result.getRowCount();
         transfer.writeInt(rowCount);
         for (int i = 0; i < columnCount; i++) {
           ResultColumn.writeColumn(transfer, result, i);
         }
         int fetch = Math.min(rowCount, fetchSize);
         for (int i = 0; i < fetch; i++) {
           sendRow(result);
         }
         transfer.flush();
         break;
       }
     case SessionRemote.COMMAND_EXECUTE_UPDATE:
       {
         int id = transfer.readInt();
         Command command = (Command) cache.getObject(id, false);
         // if(command!=null)throw new Error();
         setParameters(command);
         int old = session.getModificationId();
         int updateCount;
         synchronized (session) {
           updateCount = command.executeUpdate();
         }
         int status;
         if (session.isClosed()) {
           status = SessionRemote.STATUS_CLOSED;
         } else {
           status = getState(old);
         }
         transfer.writeInt(status).writeInt(updateCount).writeBoolean(session.getAutoCommit());
         transfer.flush();
         break;
       }
     case SessionRemote.COMMAND_CLOSE:
       {
         int id = transfer.readInt();
         Command command = (Command) cache.getObject(id, true);
         if (command != null) {
           command.close();
           cache.freeObject(id);
         }
         break;
       }
     case SessionRemote.RESULT_FETCH_ROWS:
       {
         int id = transfer.readInt();
         int count = transfer.readInt();
         ResultInterface result = (ResultInterface) cache.getObject(id, false);
         transfer.writeInt(SessionRemote.STATUS_OK);
         for (int i = 0; i < count; i++) {
           sendRow(result);
         }
         transfer.flush();
         break;
       }
     case SessionRemote.RESULT_RESET:
       {
         int id = transfer.readInt();
         ResultInterface result = (ResultInterface) cache.getObject(id, false);
         result.reset();
         break;
       }
     case SessionRemote.RESULT_CLOSE:
       {
         int id = transfer.readInt();
         ResultInterface result = (ResultInterface) cache.getObject(id, true);
         if (result != null) {
           result.close();
           cache.freeObject(id);
         }
         break;
       }
     case SessionRemote.CHANGE_ID:
       {
         int oldId = transfer.readInt();
         int newId = transfer.readInt();
         Object obj = cache.getObject(oldId, false);
         cache.freeObject(oldId);
         cache.addObject(newId, obj);
         break;
       }
     case SessionRemote.SESSION_SET_ID:
       {
         sessionId = transfer.readString();
         transfer.writeInt(SessionRemote.STATUS_OK).flush();
         break;
       }
     case SessionRemote.SESSION_SET_AUTOCOMMIT:
       {
         boolean autoCommit = transfer.readBoolean();
         session.setAutoCommit(autoCommit);
         transfer.writeInt(SessionRemote.STATUS_OK).flush();
         break;
       }
     case SessionRemote.SESSION_HAS_PENDING_TRANSACTION:
       {
         transfer
             .writeInt(SessionRemote.STATUS_OK)
             .writeInt(session.hasPendingTransaction() ? 1 : 0)
             .flush();
         break;
       }
     case SessionRemote.LOB_READ:
       {
         long lobId = transfer.readLong();
         byte[] hmac;
         CachedInputStream in;
         boolean verifyMac;
         if (clientVersion >= Constants.TCP_PROTOCOL_VERSION_11) {
           if (clientVersion >= Constants.TCP_PROTOCOL_VERSION_12) {
             hmac = transfer.readBytes();
             verifyMac = true;
           } else {
             hmac = null;
             verifyMac = false;
           }
           in = lobs.get(lobId);
           if (in == null && verifyMac) {
             in = new CachedInputStream(null);
             lobs.put(lobId, in);
           }
         } else {
           verifyMac = false;
           hmac = null;
           in = lobs.get(lobId);
         }
         long offset = transfer.readLong();
         int length = transfer.readInt();
         if (verifyMac) {
           transfer.verifyLobMac(hmac, lobId);
         }
         if (in == null) {
           throw DbException.get(ErrorCode.OBJECT_CLOSED);
         }
         if (in.getPos() != offset) {
           LobStorageInterface lobStorage = session.getDataHandler().getLobStorage();
           InputStream lobIn = lobStorage.getInputStream(lobId, hmac, -1);
           in = new CachedInputStream(lobIn);
           lobs.put(lobId, in);
           lobIn.skip(offset);
         }
         // limit the buffer size
         length = Math.min(16 * Constants.IO_BUFFER_SIZE, length);
         byte[] buff = new byte[length];
         length = IOUtils.readFully(in, buff, 0, length);
         transfer.writeInt(SessionRemote.STATUS_OK);
         transfer.writeInt(length);
         transfer.writeBytes(buff, 0, length);
         transfer.flush();
         break;
       }
     default:
       trace("Unknown operation: " + operation);
       closeSession();
       close();
   }
 }