public void removeMessage(ConnectionContext context, final MessageAck ack) throws IOException {
    final boolean debug = LOG.isDebugEnabled();
    JournalQueueAck remove = new JournalQueueAck();
    remove.setDestination(destination);
    remove.setMessageAck(ack);

    final RecordLocation location =
        peristenceAdapter.writeCommand(remove, ack.isResponseRequired());
    if (!context.isInTransaction()) {
      if (debug) {
        LOG.debug("Journalled message remove for: " + ack.getLastMessageId() + ", at: " + location);
      }
      removeMessage(ack, location);
    } else {
      if (debug) {
        LOG.debug(
            "Journalled transacted message remove for: "
                + ack.getLastMessageId()
                + ", at: "
                + location);
      }
      synchronized (this) {
        inFlightTxLocations.add(location);
      }
      transactionStore.removeMessage(this, ack, location);
      context
          .getTransaction()
          .addSynchronization(
              new Synchronization() {
                public void afterCommit() throws Exception {
                  if (debug) {
                    LOG.debug(
                        "Transacted message remove commit for: "
                            + ack.getLastMessageId()
                            + ", at: "
                            + location);
                  }
                  synchronized (JournalMessageStore.this) {
                    inFlightTxLocations.remove(location);
                    removeMessage(ack, location);
                  }
                }

                public void afterRollback() throws Exception {
                  if (debug) {
                    LOG.debug(
                        "Transacted message remove rollback for: "
                            + ack.getLastMessageId()
                            + ", at: "
                            + location);
                  }
                  synchronized (JournalMessageStore.this) {
                    inFlightTxLocations.remove(location);
                  }
                }
              });
    }
  }
  /**
   * Not synchronized since the Journal has better throughput if you increase the number of
   * concurrent writes that it is doing.
   */
  public void addMessage(final ConnectionContext context, final Message message)
      throws IOException {

    final MessageId id = message.getMessageId();

    final boolean debug = LOG.isDebugEnabled();
    message.incrementReferenceCount();

    final RecordLocation location =
        peristenceAdapter.writeCommand(message, message.isResponseRequired());
    if (!context.isInTransaction()) {
      if (debug) {
        LOG.debug("Journalled message add for: " + id + ", at: " + location);
      }
      addMessage(context, message, location);
    } else {
      if (debug) {
        LOG.debug("Journalled transacted message add for: " + id + ", at: " + location);
      }
      synchronized (this) {
        inFlightTxLocations.add(location);
      }
      transactionStore.addMessage(this, message, location);
      context
          .getTransaction()
          .addSynchronization(
              new Synchronization() {
                public void afterCommit() throws Exception {
                  if (debug) {
                    LOG.debug("Transacted message add commit for: " + id + ", at: " + location);
                  }
                  synchronized (JournalMessageStore.this) {
                    inFlightTxLocations.remove(location);
                    addMessage(context, message, location);
                  }
                }

                public void afterRollback() throws Exception {
                  if (debug) {
                    LOG.debug("Transacted message add rollback for: " + id + ", at: " + location);
                  }
                  synchronized (JournalMessageStore.this) {
                    inFlightTxLocations.remove(location);
                  }
                  message.decrementReferenceCount();
                }
              });
    }
  }