本文主要研究一下artemis的transactionTimeoutScanPeriod

transactionTimeoutScanPeriod

activemq-artemis-2.11.0/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java

public class ConfigurationImpl implements Configuration, Serializable {

   //......

   private long transactionTimeoutScanPeriod = ActiveMQDefaultConfiguration.getDefaultTransactionTimeoutScanPeriod();

   //......

   @Override
   public long getTransactionTimeoutScanPeriod() {
      return transactionTimeoutScanPeriod;
   }

   @Override
   public ConfigurationImpl setTransactionTimeoutScanPeriod(final long period) {
      transactionTimeoutScanPeriod = period;
      return this;
   }

   //......
}
  • ConfigurationImpl定义了transactionTimeoutScanPeriod属性,默认为1000

ActiveMQServerImpl

activemq-artemis-2.11.0/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java

public class ActiveMQServerImpl implements ActiveMQServer {

   //......
    
   synchronized boolean initialisePart1(boolean scalingDown) throws Exception {
       
         //......

      resourceManager = new ResourceManagerImpl((int) (configuration.getTransactionTimeout() / 1000), configuration.getTransactionTimeoutScanPeriod(), scheduledPool);

          //......
   }

   //......
}
  • ActiveMQServerImpl的initialisePart1使用configuration.getTransactionTimeout()、configuration.getTransactionTimeoutScanPeriod()、scheduledPool创建了ResourceManagerImpl

ResourceManagerImpl

activemq-artemis-2.11.0/artemis-server/src/main/java/org/apache/activemq/artemis/core/transaction/impl/ResourceManagerImpl.java

public class ResourceManagerImpl implements ResourceManager {

   private final ConcurrentMap<Xid, Transaction> transactions = new ConcurrentHashMap<>();

   private final List<HeuristicCompletionHolder> heuristicCompletions = new ArrayList<>();

   private final int defaultTimeoutSeconds;

   private boolean started = false;

   private TxTimeoutHandler task;

   private final long txTimeoutScanPeriod;

   private final ScheduledExecutorService scheduledThreadPool;

   public ResourceManagerImpl(final int defaultTimeoutSeconds,
                              final long txTimeoutScanPeriod,
                              final ScheduledExecutorService scheduledThreadPool) {
      this.defaultTimeoutSeconds = defaultTimeoutSeconds;
      this.txTimeoutScanPeriod = txTimeoutScanPeriod;
      this.scheduledThreadPool = scheduledThreadPool;
   }

   // ActiveMQComponent implementation

   @Override
   public int size() {
      return transactions.size();
   }

   @Override
   public void start() throws Exception {
      if (started) {
         return;
      }
      task = new TxTimeoutHandler();
      Future<?> future = scheduledThreadPool.scheduleAtFixedRate(task, txTimeoutScanPeriod, txTimeoutScanPeriod, TimeUnit.MILLISECONDS);
      task.setFuture(future);

      started = true;
   }

   @Override
   public void stop() throws Exception {
      if (!started) {
         return;
      }
      if (task != null) {
         task.close();
      }

      started = false;
   }

   //......
}
  • ResourceManagerImpl实现了ResourceManager接口,其start方法创建了TxTimeoutHandler,并以txTimeoutScanPeriod的fixedRate去调度执行

TxTimeoutHandler

activemq-artemis-2.11.0/artemis-server/src/main/java/org/apache/activemq/artemis/core/transaction/impl/ResourceManagerImpl.java

   private class TxTimeoutHandler implements Runnable {

      private boolean closed = false;

      private Future<?> future;

      @Override
      public void run() {
         if (closed) {
            return;
         }

         Set<Transaction> timedoutTransactions = new HashSet<>();

         long now = System.currentTimeMillis();

         for (Transaction tx : transactions.values()) {

            if (tx.hasTimedOut(now, defaultTimeoutSeconds)) {
               Transaction removedTX = removeTransaction(tx.getXid());
               if (removedTX != null) {
                  ActiveMQServerLogger.LOGGER.timedOutXID(removedTX.getXid());
                  timedoutTransactions.add(removedTX);
               }
            }
         }

         for (Transaction failedTransaction : timedoutTransactions) {
            try {
               failedTransaction.rollback();
            } catch (Exception e) {
               ActiveMQServerLogger.LOGGER.errorTimingOutTX(e, failedTransaction.getXid());
            }
         }
      }

      synchronized void setFuture(final Future<?> future) {
         this.future = future;
      }

      void close() {
         if (future != null) {
            future.cancel(false);
         }

         closed = true;
      }

   }
  • TxTimeoutHandler实现了Runnable接口,其run方法会遍历transactions,挨个执行tx.hasTimedOut(now, defaultTimeoutSeconds),对于timeout的则执行removeTransaction(tx.getXid()),之后挨个执行rollback

小结

ActiveMQServerImpl的initialisePart1使用configuration.getTransactionTimeout()、configuration.getTransactionTimeoutScanPeriod()、scheduledPool创建了ResourceManagerImpl;ResourceManagerImpl实现了ResourceManager接口,其start方法创建了TxTimeoutHandler,并以txTimeoutScanPeriod的fixedRate去调度执行;TxTimeoutHandler实现了Runnable接口,其run方法会遍历transactions,挨个执行tx.hasTimedOut(now, defaultTimeoutSeconds),对于timeout的则执行removeTransaction(tx.getXid()),之后挨个执行rollback

doc


codecraft
11.9k 声望2k 粉丝

当一个代码的工匠回首往事时,不因虚度年华而悔恨,也不因碌碌无为而羞愧,这样,当他老的时候,可以很自豪告诉世人,我曾经将代码注入生命去打造互联网的浪潮之巅,那是个很疯狂的时代,我在一波波的浪潮上留下...


引用和评论

0 条评论