private void endTransaction( // final SendResult sendResult, // final LocalTransactionState localTransactionState, // final Throwable localException) throws RemotingException, MQBrokerException, InterruptedException, UnknownHostException { final MessageId id = MessageDecoder.decodeMessageId(sendResult.getMsgId()); final String addr = RemotingUtil.socketAddress2String(id.getAddress()); EndTransactionRequestHeader requestHeader = new EndTransactionRequestHeader(); requestHeader.setCommitLogOffset(id.getOffset()); switch (localTransactionState) { case COMMIT_MESSAGE: requestHeader.setCommitOrRollback(MessageSysFlag.TransactionCommitType); break; case ROLLBACK_MESSAGE: requestHeader.setCommitOrRollback(MessageSysFlag.TransactionRollbackType); break; case UNKNOW: requestHeader.setCommitOrRollback(MessageSysFlag.TransactionNotType); break; default: break; } requestHeader.setProducerGroup(this.defaultMQProducer.getProducerGroup()); requestHeader.setTranStateTableOffset(sendResult.getQueueOffset()); requestHeader.setMsgId(sendResult.getMsgId()); String remark = localException != null ? ("executeLocalTransactionBranch exception: " + localException.toString()) : null; this.mQClientFactory .getMQClientAPIImpl() .endTransactionOneway( addr, requestHeader, remark, this.defaultMQProducer.getSendMsgTimeout()); }
public TransactionSendResult sendMessageInTransaction( final Message msg, final LocalTransactionExecuter tranExecuter, final Object arg) throws MQClientException { if (null == tranExecuter) { throw new MQClientException("tranExecuter is null", null); } // 第一步,向Broker发送一条Prepared消息 SendResult sendResult = null; msg.putProperty(MessageConst.PROPERTY_TRANSACTION_PREPARED, "true"); msg.putProperty( MessageConst.PROPERTY_PRODUCER_GROUP, this.defaultMQProducer.getProducerGroup()); try { sendResult = this.send(msg); } catch (Exception e) { throw new MQClientException("send message Exception", e); } // 第二步,回调本地事务 LocalTransactionState localTransactionState = LocalTransactionState.UNKNOW; Throwable localException = null; try { localTransactionState = tranExecuter.executeLocalTransactionBranch(msg, arg); if (null == localTransactionState) { localTransactionState = LocalTransactionState.UNKNOW; } if (localTransactionState != LocalTransactionState.COMMIT_MESSAGE) { log.info("executeLocalTransactionBranch return {}", localTransactionState); log.info(msg.toString()); } } catch (Throwable e) { log.info("executeLocalTransactionBranch exception", e); log.info(msg.toString()); localException = e; } // 第三步,提交或者回滚Broker端消息 try { this.endTransaction(sendResult, localTransactionState, localException); } catch (Exception e) { log.warn( "local transaction execute " + localTransactionState + ", but end broker transaction failed", e); } TransactionSendResult transactionSendResult = new TransactionSendResult(); transactionSendResult.setSendStatus(sendResult.getSendStatus()); transactionSendResult.setMessageQueue(sendResult.getMessageQueue()); transactionSendResult.setMsgId(sendResult.getMsgId()); transactionSendResult.setQueueOffset(sendResult.getQueueOffset()); transactionSendResult.setLocalTransactionState(localTransactionState); return transactionSendResult; }
private SendResult sendDefaultImpl( // Message msg, // final CommunicationMode communicationMode, // final SendCallback sendCallback // ) throws MQClientException, RemotingException, MQBrokerException, InterruptedException { // 有效性检查 this.makeSureStateOK(); Validators.checkMessage(msg, this.defaultMQProducer); final long beginTimestamp = System.currentTimeMillis(); long endTimestamp = beginTimestamp; TopicPublishInfo topicPublishInfo = this.tryToFindTopicPublishInfo(msg.getTopic()); if (topicPublishInfo != null && topicPublishInfo.ok()) { MessageQueue mq = null; Exception exception = null; SendResult sendResult = null; int timesTotal = 1 + this.defaultMQProducer.getRetryTimesWhenSendFailed(); for (int times = 0; times < timesTotal && (endTimestamp - beginTimestamp) < this.defaultMQProducer.getSendMsgTimeout(); times++) { String lastBrokerName = null == mq ? null : mq.getBrokerName(); MessageQueue tmpmq = topicPublishInfo.selectOneMessageQueue(lastBrokerName); if (tmpmq != null) { mq = tmpmq; try { sendResult = this.sendKernelImpl(msg, mq, communicationMode, sendCallback); endTimestamp = System.currentTimeMillis(); switch (communicationMode) { case ASYNC: return null; case ONEWAY: return null; case SYNC: if (sendResult.getSendStatus() != SendStatus.SEND_OK) { if (this.defaultMQProducer.isRetryAnotherBrokerWhenNotStoreOK()) { continue; } } return sendResult; default: break; } } catch (RemotingException e) { log.warn("sendKernelImpl exception", e); log.warn(msg.toString()); exception = e; endTimestamp = System.currentTimeMillis(); continue; } catch (MQClientException e) { log.warn("sendKernelImpl exception", e); log.warn(msg.toString()); exception = e; endTimestamp = System.currentTimeMillis(); continue; } catch (MQBrokerException e) { log.warn("sendKernelImpl exception", e); log.warn(msg.toString()); exception = e; endTimestamp = System.currentTimeMillis(); switch (e.getResponseCode()) { case MQResponseCode.TOPIC_NOT_EXIST_VALUE: case MQResponseCode.SERVICE_NOT_AVAILABLE_VALUE: case ResponseCode.SYSTEM_ERROR_VALUE: case MQResponseCode.NO_PERMISSION_VALUE: continue; default: if (sendResult != null) { return sendResult; } throw e; } } catch (InterruptedException e) { log.warn("sendKernelImpl exception", e); log.warn(msg.toString()); throw e; } } else { break; } } // end of for if (sendResult != null) { return sendResult; } throw new MQClientException("Retry many times, still failed", exception); } List<String> nsList = this.getmQClientFactory().getMQClientAPIImpl().getNameServerAddressList(); if (null == nsList || nsList.isEmpty()) { // 说明没有设置Name Server地址 throw new MQClientException( "No name server address, please set it." + FAQUrl.suggestTodo(FAQUrl.NAME_SERVER_ADDR_NOT_EXIST_URL), null); } throw new MQClientException( "No route info of this topic, " + msg.getTopic() + FAQUrl.suggestTodo(FAQUrl.NO_TOPIC_ROUTE_INFO), null); }