int doTransaction(Xid xid, int mode, int command) throws XAException {
   int returnVal = -1;
   try {
     try {
       T4CTTIOtxen otxen = physicalConn.otxen;
       byte xidxid[] = null;
       byte gtrid[] = xid.getGlobalTransactionId();
       byte bqual[] = xid.getBranchQualifier();
       int gtrid_l = 0;
       int bqual_l = 0;
       if (gtrid != null && bqual != null) {
         gtrid_l = Math.min(gtrid.length, 64);
         bqual_l = Math.min(bqual.length, 64);
         xidxid = new byte[128];
         System.arraycopy(gtrid, 0, xidxid, 0, gtrid_l);
         System.arraycopy(bqual, 0, xidxid, gtrid_l, bqual_l);
       }
       byte txctx[] = context;
       physicalConn.sendPiggyBackedMessages();
       otxen.marshal(mode, txctx, xidxid, xid.getFormatId(), gtrid_l, bqual_l, timeout, command);
       returnVal = otxen.receive(errorNumber);
     } catch (IOException ioe) {
       DatabaseError.throwSqlException(ioe);
     }
   } catch (SQLException s) {
     errorNumber[0] = s.getErrorCode();
   }
   if (errorNumber[0] == 0) {
     throw new XAException(-6);
   }
   if (returnVal == -1) {
     returnVal = errorNumber[0];
   }
   return returnVal;
 }
Exemple #2
0
 private Xid randomXid(Boolean trueForPositive) {
   while (true) {
     Xid xid = new XidImpl(randomBytes(), randomBytes());
     if (trueForPositive == null || xid.hashCode() > 0 == trueForPositive.booleanValue())
       return xid;
   }
 }
Exemple #3
0
 /** Construct an XID as a clone of another XID. */
 public JtdsXid(Xid xid) {
   fmtId = xid.getFormatId();
   gtran = new byte[xid.getGlobalTransactionId().length];
   System.arraycopy(xid.getGlobalTransactionId(), 0, gtran, 0, gtran.length);
   bqual = new byte[xid.getBranchQualifier().length];
   System.arraycopy(xid.getBranchQualifier(), 0, bqual, 0, bqual.length);
   calculateHash();
 }
 @Override
 public byte[] serialize(Xid xid) {
   return ByteBuffer.allocate(this.size())
       .putInt(xid.getFormatId())
       .put(xid.getGlobalTransactionId())
       .put(xid.getBranchQualifier())
       .array();
 }
 public boolean equals(Object object) {
   if (object instanceof Xid) {
     Xid xid = (Xid) object;
     return xid.getFormatId() == 1
         && Arrays.equals(xid.getGlobalTransactionId(), gid)
         && xid.getBranchQualifier() == null;
   } else {
     return false;
   }
 }
 private void clearRemoteTransactions(Xid xid) {
   NodeEngine nodeEngine = getNodeEngine();
   InternalPartitionService partitionService = nodeEngine.getPartitionService();
   OperationService operationService = nodeEngine.getOperationService();
   SerializableXID serializableXID =
       new SerializableXID(
           xid.getFormatId(), xid.getGlobalTransactionId(), xid.getBranchQualifier());
   Data xidData = nodeEngine.toData(serializableXID);
   int partitionId = partitionService.getPartitionId(xidData);
   ClearRemoteTransactionOperation operation = new ClearRemoteTransactionOperation(xidData);
   operationService.invokeOnPartition(SERVICE_NAME, operation, partitionId);
 }
 @Override
 public boolean equals(Object other) {
   if (other instanceof Xid) {
     Xid xid = (Xid) other;
     if (xid.getFormatId() == formatId) {
       if (Arrays.equals(branchQualifier, xid.getBranchQualifier())) {
         if (Arrays.equals(globalTransactionId, xid.getGlobalTransactionId())) {
           return true;
         }
       }
     }
   }
   return false;
 }
 private boolean isOnePhase() {
   if (resourceList.size() == 0) {
     log.severe("Detected zero resources in resourceList");
     return true;
   }
   // check for more than one unique xid
   Iterator<ResourceElement> itr = resourceList.iterator();
   Xid xid = itr.next().getXid();
   while (itr.hasNext()) {
     if (!xid.equals(itr.next().getXid())) {
       return false;
     }
   }
   return true;
 }
  public synchronized void xaStart(final Xid xid) throws Exception {
    if (tx != null) {
      HornetQServerLogger.LOGGER.xidReplacedOnXStart(tx.getXid().toString(), xid.toString());

      try {
        if (tx.getState() != Transaction.State.PREPARED) {
          // we don't want to rollback anything prepared here
          if (tx.getXid() != null) {
            resourceManager.removeTransaction(tx.getXid());
          }
          tx.rollback();
        }
      } catch (Exception e) {
        HornetQServerLogger.LOGGER.debug(
            "An exception happened while we tried to debug the previous tx, we can ignore this exception",
            e);
      }
    }

    tx = newTransaction(xid);

    if (isTrace) {
      HornetQServerLogger.LOGGER.trace("xastart into tx= " + tx);
    }

    boolean added = resourceManager.putTransaction(xid, tx);

    if (!added) {
      final String msg = "Cannot start, there is already a xid " + tx.getXid();

      throw new HornetQXAException(XAException.XAER_DUPID, msg);
    }
  }
  /**
   * Preconditions: 1. Flags is one of TMSUCCESS, TMFAIL, TMSUSPEND 2. xid != null 3. Connection is
   * associated with transaction xid
   *
   * <p>Implementation deficiency preconditions: 1. Flags is not TMSUSPEND
   *
   * <p>Postconditions: 1. connection is disassociated from the transaction.
   */
  public void end(Xid xid, int flags) throws XAException {
    if (logger.logDebug()) debug("ending transaction xid = " + xid);

    // Check preconditions

    if (flags != XAResource.TMSUSPEND
        && flags != XAResource.TMFAIL
        && flags != XAResource.TMSUCCESS)
      throw new PGXAException(GT.tr("Invalid flags"), XAException.XAER_INVAL);

    if (xid == null) throw new PGXAException(GT.tr("xid must not be null"), XAException.XAER_INVAL);

    if (state != STATE_ACTIVE || !currentXid.equals(xid))
      throw new PGXAException(
          GT.tr("tried to call end without corresponding start call"), XAException.XAER_PROTO);

    // Check implementation deficiency preconditions
    if (flags == XAResource.TMSUSPEND)
      throw new PGXAException(GT.tr("suspend/resume not implemented"), XAException.XAER_RMERR);

    // We ignore TMFAIL. It's just a hint to the RM. We could roll back immediately
    // if TMFAIL was given.

    // All clear. We don't have any real work to do.
    state = STATE_ENDED;
  }
  /**
   * Preconditions: 1. xid is known to the RM or it's in prepared state
   *
   * <p>Implementation deficiency preconditions: 1. xid must be associated with this connection if
   * it's not in prepared state.
   *
   * <p>Postconditions: 1. Transaction is rolled back and disassociated from connection
   */
  public void rollback(Xid xid) throws XAException {
    if (logger.logDebug()) debug("rolling back xid = " + xid);

    // We don't explicitly check precondition 1.

    try {
      if (currentXid != null && xid.equals(currentXid)) {
        state = STATE_IDLE;
        currentXid = null;
        conn.rollback();
        conn.setAutoCommit(localAutoCommitMode);
      } else {
        String s = RecoveredXid.xidToString(xid);

        conn.setAutoCommit(true);
        Statement stmt = conn.createStatement();
        try {
          stmt.executeUpdate("ROLLBACK PREPARED '" + s + "'");
        } finally {
          stmt.close();
        }
      }
    } catch (SQLException ex) {
      throw new PGXAException(
          GT.tr("Error rolling back prepared transaction"), ex, XAException.XAER_RMERR);
    }
  }
Exemple #12
0
  /**
   * Constructor
   *
   * @param xid The Xid
   */
  public GlobalXID(Xid xid) {
    gid = xid.getGlobalTransactionId();

    for (int i = 0; i < gid.length; ++i) hashCode += 37 * gid[i];

    toString = Arrays.toString(gid);
  }
  /**
   * Preconditions: 1. xid must in ended state.
   *
   * <p>Implementation deficiency preconditions: 1. this connection must have been used to run the
   * transaction
   *
   * <p>Postconditions: 1. Transaction is committed
   */
  private void commitOnePhase(Xid xid) throws XAException {
    try {
      // Check preconditions
      if (currentXid == null || !currentXid.equals(xid)) {
        // In fact, we don't know if xid is bogus, or if it just wasn't associated with this
        // connection.
        // Assume it's our fault.
        throw new PGXAException(
            GT.tr(
                "Not implemented: one-phase commit must be issued using the same connection that was used to start it"),
            XAException.XAER_RMERR);
      }
      if (state != STATE_ENDED)
        throw new PGXAException(GT.tr("commit called before end"), XAException.XAER_PROTO);

      // Preconditions are met. Commit
      state = STATE_IDLE;
      currentXid = null;

      conn.commit();
      conn.setAutoCommit(localAutoCommitMode);
    } catch (SQLException ex) {
      throw new PGXAException(GT.tr("Error during one-phase commit"), ex, XAException.XAER_RMERR);
    }
  }
 @Override
 public int hashCode() {
   final int prime = 31;
   int result = super.hashCode();
   result = prime * result + ((xid == null) ? 0 : xid.hashCode());
   return result;
 }
Exemple #15
0
  public final void connect() {
    while (running) {
      try {
        disconnect();

        session = sf.createXASession();

        if (activeXid != null) {
          synchronized (ClientAbstract.class) {
            Xid[] xids = session.recover(XAResource.TMSTARTRSCAN);
            boolean found = false;
            for (Xid recXid : xids) {
              if (recXid.equals(activeXid)) {
                // System.out.println("Calling commit after a prepare on " + this);
                found = true;
                callCommit();
              }
            }

            if (!found) {
              if (pendingCommit) {
                onCommit();
              } else {
                onRollback();
              }

              activeXid = null;
              pendingCommit = false;
            }
          }
        }

        connectClients();

        break;
      } catch (Exception e) {
        ClientAbstract.log.warn("Can't connect to server, retrying");
        disconnect();
        try {
          Thread.sleep(1000);
        } catch (InterruptedException ignored) {
          // if an interruption was sent, we will respect it and leave the loop
          break;
        }
      }
    }
  }
Exemple #16
0
 private void addResourceToList(Xid xid, XAResource xaRes) {
   ResourceElement element = new ResourceElement(xid, xaRes);
   if (Arrays.equals(NeoStoreXaDataSource.BRANCH_ID, xid.getBranchQualifier())) {
     resourceList.addFirst(element);
   } else {
     resourceList.add(element);
   }
 }
Exemple #17
0
  private static byte[] toByteArray(final Xid xid) {
    byte[] branchQualifier = xid.getBranchQualifier();
    byte[] globalTransactionId = xid.getGlobalTransactionId();
    int formatId = xid.getFormatId();

    byte[] hashBytes = new byte[branchQualifier.length + globalTransactionId.length + 4];
    System.arraycopy(branchQualifier, 0, hashBytes, 0, branchQualifier.length);
    System.arraycopy(
        globalTransactionId, 0, hashBytes, branchQualifier.length, globalTransactionId.length);
    byte[] intBytes = new byte[4];
    for (int i = 0; i < 4; i++) {
      intBytes[i] = (byte) ((formatId >> i * 8) % 0xFF);
    }
    System.arraycopy(
        intBytes, 0, hashBytes, branchQualifier.length + globalTransactionId.length, 4);
    return hashBytes;
  }
 protected int doEnd(Xid xid, int flag) throws XAException {
   int returnVal = -1;
   synchronized (physicalConn) {
     synchronized (this) {
       try {
         try {
           T4CTTIOtxse otxse = physicalConn.otxse;
           byte xidxid[] = null;
           byte gtrid[] = xid.getGlobalTransactionId();
           byte bqual[] = xid.getBranchQualifier();
           int gtrid_l = 0;
           int bqual_l = 0;
           if (gtrid != null && bqual != null) {
             gtrid_l = Math.min(gtrid.length, 64);
             bqual_l = Math.min(bqual.length, 64);
             xidxid = new byte[128];
             System.arraycopy(gtrid, 0, xidxid, 0, gtrid_l);
             System.arraycopy(bqual, 0, xidxid, gtrid_l, bqual_l);
           }
           byte txctx[] = context;
           int t4cflag = 0;
           if (((flag & 2) == 2 || (flag & 0x100000) != 0x100000)
               && (flag & 0x2000000) == 0x2000000) {
             t4cflag = 0x100000;
           }
           physicalConn.sendPiggyBackedMessages();
           otxse.marshal(2, txctx, xidxid, xid.getFormatId(), gtrid_l, bqual_l, timeout, t4cflag);
           byte ctx[] = otxse.receive(applicationValueArr);
           if (ctx != null) {
             context = ctx;
           }
           returnVal = 0;
         } catch (IOException ioe) {
           DatabaseError.throwSqlException(ioe);
         }
       } catch (SQLException s) {
         returnVal = s.getErrorCode();
         if (returnVal == 0) {
           throw new XAException(-6);
         }
       }
     }
   }
   return returnVal;
 }
 @Override
 public boolean equals(Object obj) {
   if (this == obj) return true;
   if (!super.equals(obj)) return false;
   if (!(obj instanceof SessionXAJoinMessage)) return false;
   SessionXAJoinMessage other = (SessionXAJoinMessage) obj;
   if (xid == null) {
     if (other.xid != null) return false;
   } else if (!xid.equals(other.xid)) return false;
   return true;
 }
  public boolean equals(Object another) {

    if (another instanceof Xid) {
      Xid anotherAsXid = (Xid) another;

      if (this.myFormatId != anotherAsXid.getFormatId()) {
        return false;
      }

      byte[] otherBqual = anotherAsXid.getBranchQualifier();
      byte[] otherGtrid = anotherAsXid.getGlobalTransactionId();

      if (otherGtrid != null && otherGtrid.length == this.myGtrid.length) {
        int length = otherGtrid.length;

        for (int i = 0; i < length; i++) {
          if (otherGtrid[i] != this.myGtrid[i]) {
            return false;
          }
        }

        if (otherBqual != null && otherBqual.length == myBqual.length) {
          length = otherBqual.length;

          for (int i = 0; i < length; i++) {
            if (otherBqual[i] != this.myBqual[i]) {
              return false;
            }
          }
        } else {
          return false;
        }

        return true;
      } else {
        return false;
      }
    } else {
      return false;
    }
  }
Exemple #21
0
  private Xid createXid(Xid xidToBranch) throws IOException {
    ByteArrayOutputStream bqualOut = new ByteArrayOutputStream();
    DataOutputStream dataOut = new DataOutputStream(bqualOut);

    new UID().write(dataOut);

    final byte[] bqual = bqualOut.toByteArray();

    Xid xid = new MysqlXid(xidToBranch.getGlobalTransactionId(), bqual, 3306);

    return xid;
  }
Exemple #22
0
 @Override
 public boolean equals(final Object other) {
   if (this == other) {
     return true;
   }
   if (!(other instanceof Xid)) {
     return false;
   }
   Xid xother = (Xid) other;
   if (xother.getFormatId() != formatId) {
     return false;
   }
   if (xother.getBranchQualifier().length != branchQualifier.length) {
     return false;
   }
   if (xother.getGlobalTransactionId().length != globalTransactionId.length) {
     return false;
   }
   for (int i = 0; i < branchQualifier.length; i++) {
     byte[] otherBQ = xother.getBranchQualifier();
     if (branchQualifier[i] != otherBQ[i]) {
       return false;
     }
   }
   for (int i = 0; i < globalTransactionId.length; i++) {
     byte[] otherGtx = xother.getGlobalTransactionId();
     if (globalTransactionId[i] != otherGtx[i]) {
       return false;
     }
   }
   return true;
 }
Exemple #23
0
  public static void assertSameXids(final List<Xid> expected, final List<Xid> actual) {
    Assert.assertNotNull(expected);
    Assert.assertNotNull(actual);
    Assert.assertEquals(expected.size(), actual.size());

    for (int i = 0; i < expected.size(); i++) {
      Xid expectedXid = expected.get(i);
      Xid actualXid = actual.get(i);
      UnitTestCase.assertEqualsByteArrays(
          expectedXid.getBranchQualifier(), actualXid.getBranchQualifier());
      Assert.assertEquals(expectedXid.getFormatId(), actualXid.getFormatId());
      UnitTestCase.assertEqualsByteArrays(
          expectedXid.getGlobalTransactionId(), actualXid.getGlobalTransactionId());
    }
  }
Exemple #24
0
 private void finalizeTransactionRemotely(Xid xid, boolean isCommit) throws XAException {
   NodeEngine nodeEngine = getNodeEngine();
   InternalPartitionService partitionService = nodeEngine.getPartitionService();
   OperationService operationService = nodeEngine.getOperationService();
   SerializableXID serializableXID =
       new SerializableXID(
           xid.getFormatId(), xid.getGlobalTransactionId(), xid.getBranchQualifier());
   Data xidData = nodeEngine.toData(serializableXID);
   int partitionId = partitionService.getPartitionId(xidData);
   FinalizeRemoteTransactionOperation operation =
       new FinalizeRemoteTransactionOperation(xidData, isCommit);
   InternalCompletableFuture<Integer> future =
       operationService.invokeOnPartition(SERVICE_NAME, operation, partitionId);
   Integer errorCode;
   try {
     errorCode = future.get();
   } catch (Exception e) {
     throw ExceptionUtil.rethrow(e);
   }
   if (errorCode != null) {
     throw new XAException(errorCode);
   }
 }
  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (!(o instanceof Xid)) {
      return false;
    }

    Xid that = (Xid) o;

    if (formatId != that.getFormatId()) {
      return false;
    }
    if (!Arrays.equals(branchQualifier, that.getBranchQualifier())) {
      return false;
    }
    if (!Arrays.equals(globalTransactionId, that.getGlobalTransactionId())) {
      return false;
    }

    return true;
  }
  /**
   * @throws XAException if the given Xid is the not the Xid of the current transaction for this
   *     XAResource object.
   */
  private void validateXid(Xid xid) throws XAException {

    if (xid == null) {
      throw new XAException("Null Xid");
    }

    if (this.xid == null) {
      throw new XAException("There is no live transaction for this XAResource");
    }

    if (!xid.equals(this.xid)) {
      throw new XAException("Given Xid is not that associated with this XAResource object");
    }
  }
 private boolean equals(Xid xid1, Xid xid2) {
   if (xid1 == xid2) {
     return true;
   }
   if (xid1 == null ^ xid2 == null) {
     return false;
   }
   return xid1.getFormatId() == xid2.getFormatId()
       && Arrays.equals(xid1.getBranchQualifier(), xid2.getBranchQualifier())
       && Arrays.equals(xid1.getGlobalTransactionId(), xid2.getGlobalTransactionId());
 }
 public RemoteTransaction removeRemoteTransaction(Xid xid) {
   if (clustered) {
     Iterator<RemoteTransaction> it = getRemoteTransactions().iterator();
     while (it.hasNext()) {
       RemoteTransaction next = it.next();
       RecoverableTransactionIdentifier gtx =
           (RecoverableTransactionIdentifier) next.getGlobalTransaction();
       if (xid.equals(gtx.getXid())) {
         it.remove();
         recalculateMinTopologyIdIfNeeded(next);
         next.notifyOnTransactionFinished();
         return next;
       }
     }
   }
   return null;
 }
  /**
   * Preconditions: 1. flags must be one of TMNOFLAGS, TMRESUME or TMJOIN 2. xid != null 3.
   * connection must not be associated with a transaction 4. the TM hasn't seen the xid before
   *
   * <p>Implementation deficiency preconditions: 1. TMRESUME not supported. 2. if flags is TMJOIN,
   * we must be in ended state, and xid must be the current transaction 3. unless flags is TMJOIN,
   * previous transaction using the connection must be committed or prepared or rolled back
   *
   * <p>Postconditions: 1. Connection is associated with the transaction
   */
  public void start(Xid xid, int flags) throws XAException {
    if (logger.logDebug()) debug("starting transaction xid = " + xid);

    // Check preconditions
    if (flags != XAResource.TMNOFLAGS && flags != XAResource.TMRESUME && flags != XAResource.TMJOIN)
      throw new PGXAException(GT.tr("Invalid flags"), XAException.XAER_INVAL);

    if (xid == null) throw new PGXAException(GT.tr("xid must not be null"), XAException.XAER_INVAL);

    if (state == STATE_ACTIVE)
      throw new PGXAException(
          GT.tr("Connection is busy with another transaction"), XAException.XAER_PROTO);

    // We can't check precondition 4 easily, so we don't. Duplicate xid will be catched in prepare
    // phase.

    // Check implementation deficiency preconditions
    if (flags == TMRESUME)
      throw new PGXAException(GT.tr("suspend/resume not implemented"), XAException.XAER_RMERR);

    // It's ok to join an ended transaction. WebLogic does that.
    if (flags == TMJOIN) {
      if (state != STATE_ENDED)
        throw new PGXAException(
            GT.tr("Transaction interleaving not implemented"), XAException.XAER_RMERR);

      if (!xid.equals(currentXid))
        throw new PGXAException(
            GT.tr("Transaction interleaving not implemented"), XAException.XAER_RMERR);
    } else if (state == STATE_ENDED)
      throw new PGXAException(
          GT.tr("Transaction interleaving not implemented"), XAException.XAER_RMERR);

    try {
      localAutoCommitMode = conn.getAutoCommit();
      conn.setAutoCommit(false);
    } catch (SQLException ex) {
      throw new PGXAException(GT.tr("Error disabling autocommit"), ex, XAException.XAER_RMERR);
    }

    // Preconditions are met, Associate connection with the transaction
    state = STATE_ACTIVE;
    currentXid = xid;
  }
  /**
   * Preconditions: 1. xid != null 2. xid is in ended state
   *
   * <p>Implementation deficiency preconditions: 1. xid was associated with this connection
   *
   * <p>Postconditions: 1. Transaction is prepared
   */
  public int prepare(Xid xid) throws XAException {
    if (logger.logDebug()) debug("preparing transaction xid = " + xid);

    // Check preconditions
    if (!currentXid.equals(xid)) {
      throw new PGXAException(
          GT.tr(
              "Not implemented: Prepare must be issued using the same connection that started the transaction"),
          XAException.XAER_RMERR);
    }
    if (state != STATE_ENDED)
      throw new PGXAException(GT.tr("Prepare called before end"), XAException.XAER_INVAL);

    state = STATE_IDLE;
    currentXid = null;

    if (!conn.haveMinimumServerVersion("8.1"))
      throw new PGXAException(
          GT.tr("Server versions prior to 8.1 do not support two-phase commit."),
          XAException.XAER_RMERR);

    try {
      String s = RecoveredXid.xidToString(xid);

      Statement stmt = conn.createStatement();
      try {
        stmt.executeUpdate("PREPARE TRANSACTION '" + s + "'");
      } finally {
        stmt.close();
      }
      conn.setAutoCommit(localAutoCommitMode);

      return XA_OK;
    } catch (SQLException ex) {
      throw new PGXAException(GT.tr("Error preparing transaction"), ex, XAException.XAER_RMERR);
    }
  }