예제 #1
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;
 }
예제 #2
0
 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());
 }
예제 #3
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());
    }
  }
예제 #4
0
 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;
 }
 @Override
 public byte[] serialize(Xid xid) {
   return ByteBuffer.allocate(this.size())
       .putInt(xid.getFormatId())
       .put(xid.getGlobalTransactionId())
       .put(xid.getBranchQualifier())
       .array();
 }
예제 #6
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();
 }
예제 #7
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);
   }
 }
예제 #8
0
 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;
   }
 }
예제 #9
0
 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);
 }
예제 #10
0
 @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;
 }
예제 #11
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;
  }
예제 #12
0
 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;
 }
예제 #13
0
  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;
    }
  }
예제 #14
0
  @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;
  }
예제 #15
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);
   }
 }
예제 #16
0
  protected int doStart(Xid xid, int flag) throws XAException {
    int returnVal = -1;

    synchronized (this.physicalConn) {
      synchronized (this) {
        if (this.isTransLoose) {
          flag |= 65536;
        }

        int swtch = flag & 0x8200000;

        if ((swtch == 134217728) && (OracleXid.isLocalTransaction(xid))) {
          return 0;
        }

        this.applicationValueArr[0] = 0;
        try {
          try {
            T4CTTIOtxse otxse = this.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['\u0080'];

              System.arraycopy(gtrid, 0, xidxid, 0, gtrid_l);
              System.arraycopy(bqual, 0, xidxid, gtrid_l, bqual_l);
            }

            int t4cflag = 0;

            if (((flag & 0x200000) != 0) || ((flag & 0x8000000) != 0)) t4cflag |= 4;
            else {
              t4cflag |= 1;
            }
            if ((flag & 0x100) != 0) {
              t4cflag |= 256;
            }
            if ((flag & 0x200) != 0) {
              t4cflag |= 512;
            }
            if ((flag & 0x400) != 0) {
              t4cflag |= 1024;
            }
            if ((flag & 0x10000) != 0) {
              t4cflag |= 65536;
            }
            this.physicalConn.sendPiggyBackedMessages();
            otxse.marshal(
                1, null, xidxid, xid.getFormatId(), gtrid_l, bqual_l, this.timeout, t4cflag);

            byte[] ctx = otxse.receive(this.applicationValueArr);

            if (ctx != null) {
              this.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;
  }
예제 #17
0
 private void forgetWithXid(int nodeIndex) {
   Xid xid = tx.getXid();
   recoveryOps(nodeIndex)
       .forget(xid.getFormatId(), xid.getGlobalTransactionId(), xid.getBranchQualifier());
   assertEquals(tt(1).getRemoteTxCount(), 0); // make sure tx has been removed
 }
예제 #18
0
 public XATransactionId(final Xid xid) {
   this.formatId = xid.getFormatId();
   this.globalTransactionId = xid.getGlobalTransactionId();
   this.branchQualifier = xid.getBranchQualifier();
 }
예제 #19
0
  /** Recover all datasources */
  public void recover(Iterator<List<TxLog.Record>> knownDanglingRecordList) {
    // contains NonCompletedTransaction that needs to be committed
    List<NonCompletedTransaction> commitList = new ArrayList<NonCompletedTransaction>();

    // contains Xids that should be rolledback
    final List<Xid> rollbackList = new LinkedList<Xid>();

    // key = Resource(branchId) value = XAResource
    final Map<Resource, XaDataSource> resourceMap = new HashMap<Resource, XaDataSource>();
    buildRecoveryInfo(commitList, rollbackList, resourceMap, knownDanglingRecordList);
    // invoke recover on all xa resources found
    final List<Xid> recoveredXidsList = new LinkedList<Xid>();

    try {

      for (XaDataSource xaDataSource : dataSources.values()) {
        XAResource xaRes = xaDataSource.getXaConnection().getXaResource();
        Xid xids[] = xaRes.recover(XAResource.TMNOFLAGS);

        for (Xid xid : xids) {
          if (XidImpl.isThisTm(xid.getGlobalTransactionId())) {
            // linear search
            if (rollbackList.contains(xid)) {
              msgLog.logMessage("TM: Found pre commit " + xid + " rolling back ... ", true);
              rollbackList.remove(xid);
              xaRes.rollback(xid);
            } else {
              Resource resource = new Resource(xid.getBranchQualifier());
              if (!resourceMap.containsKey(resource)) {
                resourceMap.put(resource, xaDataSource);
              }
              recoveredXidsList.add(xid);
            }
          } else {
            msgLog.warn("Unknown xid: " + xid);
          }
        }
      }

      // sort the commit list after sequence number
      Collections.sort(commitList);

      // go through and commit
      for (NonCompletedTransaction nct : commitList) {
        int seq = nct.getSequenceNumber();
        Xid xids[] = nct.getXids();
        msgLog.debug("Marked as commit tx-seq[" + seq + "] branch length: " + xids.length);
        for (Xid xid : xids) {
          if (!recoveredXidsList.contains(xid)) {
            msgLog.debug(
                "Tx-seq["
                    + seq
                    + "]["
                    + xid
                    + "] not found in recovered xid list, "
                    + "assuming already committed");
            continue;
          }
          recoveredXidsList.remove(xid);
          Resource resource = new Resource(xid.getBranchQualifier());
          if (!resourceMap.containsKey(resource)) {
            final TransactionFailureException ex =
                new TransactionFailureException("Couldn't find XAResource for " + xid);
            throw logAndReturn("TM: recovery error", ex);
          }
          msgLog.debug("TM: Committing tx " + xid);
          resourceMap.get(resource).getXaConnection().getXaResource().commit(xid, false);
        }
      }

      // rollback the rest
      for (Xid xid : recoveredXidsList) {
        Resource resource = new Resource(xid.getBranchQualifier());
        if (!resourceMap.containsKey(resource)) {
          final TransactionFailureException ex =
              new TransactionFailureException("Couldn't find XAResource for " + xid);
          throw logAndReturn("TM: recovery error", ex);
        }
        msgLog.debug("TM: no match found for " + xid + " removing");
        resourceMap.get(resource).getXaConnection().getXaResource().rollback(xid);
      }
      if (rollbackList.size() > 0) {
        msgLog.debug(
            "TxLog contained unresolved "
                + "xids that needed rollback. They couldn't be matched to "
                + "any of the XAResources recover list. "
                + "Assuming "
                + rollbackList.size()
                + " transactions already rolled back.");
      }

      // Rotate the logs of the participated data sources, making sure that
      // done-records are written so that even if the tm log gets truncated,
      // which it will be after this recovery, that transaction information
      // doesn't get lost.
      for (XaDataSource participant : MapUtil.reverse(resourceMap).keySet()) {
        participant.rotateLogicalLog();
      }
    } catch (IOException | XAException e) {
      throw logAndReturn(
          "TM: recovery failed", new TransactionFailureException("Recovery failed.", e));
    }
  }
예제 #20
0
 /**
  * Copy constructor
  *
  * @param other
  */
 public XidImpl(final Xid other) {
   branchQualifier = copyBytes(other.getBranchQualifier());
   formatId = other.getFormatId();
   globalTransactionId = copyBytes(other.getGlobalTransactionId());
 }
예제 #21
0
 public void testInternalIdOnSameNode() throws Exception {
   Xid xid = tx.getXid();
   recoveryOps(0)
       .forget(xid.getFormatId(), xid.getGlobalTransactionId(), xid.getBranchQualifier());
   assertEquals(tt(1).getRemoteTxCount(), 0); // make sure tx has been removed
 }