Uploaded image for project: 'Geode'
  1. Geode
  2. GEODE-8846

Transaction commit fail when uniqueID integer overflow to negative value

    XMLWordPrintableJSON

Details

    Description

      When client increments uniqId above Integer.MAX_VALUE (2147483647) then due to memory overflow the uniqId is set to negative value Integer.MIN_VALUE (-2147483648). TransactionID (uniqId) is sent to the server as a part of transaction message.

      public class TXManagerImpl implements CacheTransactionManager, MembershipListener {
      ...
        // The unique transaction ID for this Manager
        private final AtomicInteger uniqId;
      ....
          TXId id = new TXId(this.distributionMgrId, this.uniqId.incrementAndGet());
      ....
      

      Currently server will interpret any negative value of transactionID (uniqID) as non-transactional traffic. Please notice that getTransactionID() actually retrieves uniqID value that is set by client.

      /**
       * checks to see if this thread needs to masquerade as a transactional thread. clients after
       * GFE_66 should be able to start a transaction.
       *
       * @return true if thread should masquerade as a transactional thread.
       */
      protected boolean shouldMasqueradeForTx(Message clientMessage,
          ServerConnection serverConnection) {
        return serverConnection.getClientVersion().isNotOlderThan(KnownVersion.GFE_66)
            && clientMessage.getTransactionId() > TXManagerImpl.NOTX; // ---> NOTX is equal -1
      }
      

      After overflow happens all subsequent commit actions from the client are rejected with exception:

      [vm0] [fatal 2021/01/14 15:28:41.967 CET <ServerConnection on port 39093 Thread 2> tid=0x52] Server connection from [identity(192.168.90.23(29826:loner):48210:6c694c01,connection=1; port=48212] : Unexpected Error on server
      [vm0] org.apache.geode.InternalGemFireError
      [vm0] at org.apache.geode.internal.Assert.throwError(Assert.java:91)
      [vm0] at org.apache.geode.internal.Assert.assertTrue(Assert.java:55)
      [vm0] at org.apache.geode.internal.cache.tier.sockets.command.CommitCommand.cmdExecute(CommitCommand.java:82)
      [vm0] at org.apache.geode.internal.cache.tier.sockets.BaseCommand.execute(BaseCommand.java:183)
      [vm0] at org.apache.geode.internal.cache.tier.sockets.ServerConnection.doNormalMessage(ServerConnection.java:848)
      [vm0] at org.apache.geode.internal.cache.tier.sockets.OriginalServerConnection.doOneMessage(OriginalServerConnection.java:72)
      [vm0] at org.apache.geode.internal.cache.tier.sockets.ServerConnection.run(ServerConnection.java:1214)
      [vm0] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
      [vm0] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
      [vm0] at org.apache.geode.internal.cache.tier.sockets.AcceptorImpl.lambda$initializeServerConnectionThreadPool$3(AcceptorImpl.java:691)
      [vm0] at org.apache.geode.logging.internal.executors.LoggingThreadFactory.lambda$newThread$0(LoggingThreadFactory.java:120)
      [vm0] at java.lang.Thread.run(Thread.java:748)

      Attachments

        Issue Links

          Activity

            People

              jvarenina Jakov Varenina
              jvarenina Jakov Varenina
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: