@Override
 public void publish(EventMessage... events) {
   final Channel channel = connectionFactory.createConnection().createChannel(isTransactional);
   try {
     for (EventMessage event : events) {
       doSendMessage(
           channel,
           routingKeyResolver.resolveRoutingKey(event),
           asByteArray(event),
           isDurable ? DURABLE : null);
     }
     if (CurrentUnitOfWork.isStarted()) {
       CurrentUnitOfWork.get().registerListener(new ChannelTransactionUnitOfWorkListener(channel));
     } else if (isTransactional) {
       channel.txCommit();
     }
   } catch (IOException e) {
     if (isTransactional) {
       tryRollback(channel);
     }
     throw new EventPublicationFailedException(
         "Failed to dispatch Events to the Message Broker.", e);
   } catch (ShutdownSignalException e) {
     throw new EventPublicationFailedException(
         "Failed to dispatch Events to the Message Broker.", e);
   } finally {
     if (!CurrentUnitOfWork.isStarted()) {
       tryClose(channel);
     }
   }
 }
 @Override
 public void afterCommit() {
   if (isOpen) {
     try {
       if (isTransactional) {
         channel.txCommit();
       }
     } catch (IOException e) {
       logger.warn("Unable to commit transaction on channel.", e);
     }
     tryClose(channel);
   }
 }
  @Override
  protected <E> boolean transactionalPublishImpl(
      Collection<E> messageBundles, TransportPublishProperties properties)
      throws IOException, TimeoutException, InterruptedException {
    channel.txSelect();

    boolean rollback = true;

    try {
      for (E messageBundle : messageBundles) {
        if (!publishImpl((AMQPMessageBundle) messageBundle, properties)) return false;
      }
      rollback = false;
    } finally {
      // ! Explicitly roll back.
      if (rollback) channel.txRollback();
      else channel.txCommit();
    }

    return !rollback;
  }