/**
   * Prepare the given Connection with the given transaction semantics.
   *
   * @param con the Connection to prepare
   * @param definition the transaction definition to apply
   * @return the previous isolation level, if any
   * @throws SQLException if thrown by JDBC methods
   * @see #resetConnectionAfterTransaction
   */
  public static Integer prepareConnectionForTransaction(
      Connection con, TransactionDefinition definition) throws SQLException {

    Assert.notNull(con, "No Connection specified");

    // Set read-only flag.
    if (definition != null && definition.isReadOnly()) {
      try {
        if (logger.isDebugEnabled()) {
          logger.debug("Setting JDBC Connection [" + con + "] read-only");
        }
        con.setReadOnly(true);
      } catch (Throwable ex) {
        // SQLException or UnsupportedOperationException
        // -> ignore, it's just a hint anyway.
        logger.debug("Could not set JDBC Connection read-only", ex);
      }
    }

    // Apply specific isolation level, if any.
    Integer previousIsolationLevel = null;
    if (definition != null
        && definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
      if (logger.isDebugEnabled()) {
        logger.debug(
            "Changing isolation level of JDBC Connection ["
                + con
                + "] to "
                + definition.getIsolationLevel());
      }
      previousIsolationLevel = con.getTransactionIsolation();
      con.setTransactionIsolation(definition.getIsolationLevel());
    }

    return previousIsolationLevel;
  }
  @Override
  protected void doJtaBegin(JtaTransactionObject txObject, TransactionDefinition definition)
      throws NotSupportedException, SystemException {

    int timeout = determineTimeout(definition);

    // Apply transaction name (if any) to WebLogic transaction.
    if (this.weblogicUserTransactionAvailable && definition.getName() != null) {
      try {
        if (timeout > TransactionDefinition.TIMEOUT_DEFAULT) {
          /*
          weblogic.transaction.UserTransaction wut = (weblogic.transaction.UserTransaction) ut;
          wut.begin(definition.getName(), timeout);
          */
          this.beginWithNameAndTimeoutMethod.invoke(
              txObject.getUserTransaction(), definition.getName(), timeout);
        } else {
          /*
          weblogic.transaction.UserTransaction wut = (weblogic.transaction.UserTransaction) ut;
          wut.begin(definition.getName());
          */
          this.beginWithNameMethod.invoke(txObject.getUserTransaction(), definition.getName());
        }
      } catch (InvocationTargetException ex) {
        throw new TransactionSystemException(
            "WebLogic's UserTransaction.begin() method failed", ex.getTargetException());
      } catch (Exception ex) {
        throw new TransactionSystemException(
            "Could not invoke WebLogic's UserTransaction.begin() method", ex);
      }
    } else {
      // No WebLogic UserTransaction available or no transaction name specified
      // -> standard JTA begin call.
      applyTimeout(txObject, timeout);
      txObject.getUserTransaction().begin();
    }

    // Specify isolation level, if any, through corresponding WebLogic transaction property.
    if (this.weblogicTransactionManagerAvailable) {
      if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
        try {
          Transaction tx = getTransactionManager().getTransaction();
          Integer isolationLevel = definition.getIsolationLevel();
          /*
          weblogic.transaction.Transaction wtx = (weblogic.transaction.Transaction) tx;
          wtx.setProperty(ISOLATION_LEVEL_KEY, isolationLevel);
          */
          this.setPropertyMethod.invoke(tx, ISOLATION_LEVEL_KEY, isolationLevel);
        } catch (InvocationTargetException ex) {
          throw new TransactionSystemException(
              "WebLogic's Transaction.setProperty(String, Serializable) method failed",
              ex.getTargetException());
        } catch (Exception ex) {
          throw new TransactionSystemException(
              "Could not invoke WebLogic's Transaction.setProperty(String, Serializable) method",
              ex);
        }
      }
    } else {
      applyIsolationLevel(txObject, definition.getIsolationLevel());
    }
  }