Пример #1
0
  private void updateTransactionStatus() throws SQLException {
    // if there is a is an active transaction context, assure the transaction context hasn't changed
    if (transactionContext != null) {
      if (transactionContext.isActive()) {
        if (transactionContext != transactionRegistry.getActiveTransactionContext()) {
          throw new SQLException(
              "Connection can not be used while enlisted in another transaction");
        }
        return;
      } else {
        // transaction should have been cleared up by TransactionContextListener, but in
        // rare cases another lister could have registered which uses the connection before
        // our listener is called.  In that rare case, trigger the transaction complete call now
        transactionComplete();
      }
    }

    // the existing transaction context ended (or we didn't have one), get the active transaction
    // context
    transactionContext = transactionRegistry.getActiveTransactionContext();

    // if there is an active transaction context and it already has a shared connection, use it
    if (transactionContext != null && transactionContext.getSharedConnection() != null) {
      // A connection for the connection factory has already been enrolled
      // in the transaction, replace our delegate with the enrolled connection

      // return current connection to the pool
      Connection connection = getDelegateInternal();
      setDelegate(null);
      if (connection != null) {
        try {
          pool.returnObject(connection);
        } catch (Exception ignored) {
          // whatever... try to invalidate the connection
          try {
            pool.invalidateObject(connection);
          } catch (Exception ignore) {
            // no big deal
          }
        }
      }

      // add a listener to the transaction context
      transactionContext.addTransactionContextListener(new CompletionListener());

      // set our delegate to the shared connection
      setDelegate(transactionContext.getSharedConnection());

      // remember that we are using a shared connection so it can be cleared after the
      // transaction completes
      isSharedConnection = true;
    } else {
      // if our delegate is null, create one
      if (getDelegateInternal() == null) {
        try {
          // borrow a new connection from the pool
          Connection connection = (Connection) pool.borrowObject();
          setDelegate(connection);
        } catch (Exception e) {
          throw (SQLException)
              new SQLException("Unable to acquire a new connection from the pool").initCause(e);
        }
      }

      // if we have a transaction, out delegate becomes the shared delegate
      if (transactionContext != null) {
        // add a listener to the transaction context
        transactionContext.addTransactionContextListener(new CompletionListener());

        // register our connection as the shared connection
        try {
          transactionContext.setSharedConnection(getDelegateInternal());
        } catch (SQLException e) {
          // transaction is hosed
          transactionContext = null;
          throw e;
        }
      }
    }
  }