All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alibaba.tmq.client.system.producer.implement.DefaultTransactionProducer Maven / Gradle / Ivy

package com.alibaba.tmq.client.system.producer.implement;

import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.alibaba.tmq.client.TMQFactory;
import com.alibaba.tmq.client.system.producer.TransactionProducer;
import com.alibaba.tmq.client.system.producer.config.ProducerConfig;
import com.alibaba.tmq.client.system.producer.executer.LocalTransactionExecuter;
import com.alibaba.tmq.client.system.producer.executer.ProducerExecuter;
import com.alibaba.tmq.client.util.StringUtil;
import com.alibaba.tmq.common.constants.Constants;
import com.alibaba.tmq.common.context.InvocationContext;
import com.alibaba.tmq.common.domain.*;
import com.alibaba.tmq.common.domain.remoting.ConnectionChannel;
import com.alibaba.tmq.common.domain.result.Result;
import com.alibaba.tmq.common.domain.result.ResultCode;
import com.alibaba.tmq.common.domain.result.SendResult;
import com.alibaba.tmq.common.exception.TMQException;
import com.alibaba.tmq.common.service.ServerService;
import com.alibaba.tmq.common.util.MessageUtil;

/**
 * 默认事务生产者
 * @author tianyao.myc
 *
 */
public class DefaultTransactionProducer extends DefaultProducer implements TransactionProducer, Constants {

	private static final Log logger = LogFactory.getLog(DefaultTransactionProducer.class);
	
	/** 服务端基础服务 */
	private final ServerService serverService = clientRemoting.proxyInterface(ServerService.class);
	
	/** 各项参数配置 */
	private final ProducerConfig producerConfig;
	
	private final ProducerExecuter producerExecuter;
	
	public DefaultTransactionProducer(ProducerConfig producerConfig, ProducerExecuter producerExecuter) {
		
		super(producerConfig, producerExecuter);
		
		this.producerConfig = producerConfig;
		this.producerExecuter = producerExecuter;
	}
	
	/**
	 * 发送事物消息
	 */
	public SendResult send(Message message, LocalTransactionExecuter localTransactionExecuter, Object object) throws TMQException {

		//重置参数,防止用户设置参数导致系统运行错误
		if(StringUtil.isNotBlank(clientConfig.getBackupDomainName())) {
			MessageUtil.reset(message, clientConfig.getBackupClusterId());
		} else {
			MessageUtil.reset(message, clientConfig.getClusterId());
		}
		
		//检查消息是否正确
		Result checkResult = MessageUtil.check4Send(message);
		if(! checkResult.getData().booleanValue()) {
			return new SendResult(checkResult);
		}
		
		//渲染消息
		KeyValuePair messageKeyValue = MessageUtil.renderingMessage(
				this.producerConfig.getProducerId(), message, MessageStatus.INITIALIZATION, MessageType.TRANSACTION_ONCE);
		
		/** 获取该消息要触发的那台Server */
		String server = clientRemoting.acquireFireServer(message.getMessageKey());
		if(StringUtil.isBlank(server)) {
			return new SendResult(false, ResultCode.SERVER_ERROR, messageKeyValue);
		}
		
		Result sendResult = null;
		try {
			InvocationContext.setConnectionChannel(new ConnectionChannel(server, ROLE_TYPE_PRODUCER, this.producerConfig.getProducerId()));
			sendResult = serverService.send(message);//发送半消息
		} catch (Throwable e) {
			logger.error("[DefaultTransactionProducer]: send message error, message:" + message, e);
		}
		
		if(null == sendResult) {
			return new SendResult(false, ResultCode.HALF_MESSAGE_ERROR, messageKeyValue);//如果返回值是null那就是超时了
		}
		
		if(! sendResult.getData().booleanValue()) {
			return new SendResult(false, sendResult.getResultCode(), messageKeyValue);//发送消息失败
		}
		
		//执行业务逻辑
		TransactionStatus transactionStatus = TransactionStatus.UnKnow;
		try {
			transactionStatus = localTransactionExecuter.execute(object);
		} catch (Throwable e) {
			logger.error("[DefaultTransactionProducer]: execute message error, message:" + message, e);
			transactionStatus = TransactionStatus.Rollback;
		}
		
		if(null == transactionStatus) {
			transactionStatus = TransactionStatus.UnKnow;//用户返回null 就不知道该干啥
		}
		
		switch(transactionStatus) {
		case UnKnow:
			
			return new SendResult(false, ResultCode.UNKNOW_TRANSACTION_STATUS_ERROR, messageKeyValue);
		case Commit:
			
			//将消息设置为待发送状态
			MessageUtil.setMessageStatus(message, MessageStatus.READY_TO_FIRE);
			
			break ;
		case Rollback:
			
			//将消息设置为丢弃状态
			MessageUtil.setMessageStatus(message, MessageStatus.DISCARD);
			
			break ;
			default:
		}

		//发送确认消息
		Result updateResult = null;
		try {
			InvocationContext.setConnectionChannel(new ConnectionChannel(server, ROLE_TYPE_PRODUCER, this.producerConfig.getProducerId()));
			updateResult = serverService.update(message);
		} catch (Throwable e) {
			logger.error("[DefaultTransactionProducer]: confirm message error, message:" + message, e);
		}
		
		if(null == updateResult) {
			return new SendResult(false, ResultCode.CONFIRM_MESSAGE_TIMEOUT, messageKeyValue);//如果返回值是null那就是超时了
		}
		
		return new SendResult(updateResult, messageKeyValue);
	}

	/**
	 * 批量发送事物消息
	 */
	public SendResult send(List messageList, LocalTransactionExecuter localTransactionExecuter, Object object) throws TMQException {

		//重置参数,防止用户设置参数导致系统运行错误
		if(StringUtil.isNotBlank(clientConfig.getBackupDomainName())) {
			MessageUtil.reset(messageList, clientConfig.getBackupClusterId());
		} else {
			MessageUtil.reset(messageList, clientConfig.getClusterId());
		}

		//检查消息是否正确
		Result checkResult = MessageUtil.check4Send(messageList);
		if(! checkResult.getData().booleanValue()) {
			return new SendResult(checkResult);
		}
		
		//渲染消息列表
		List> messageKeyValueList = MessageUtil.renderingMessage(
				this.producerConfig.getProducerId(), messageList, MessageStatus.READY_TO_FIRE, MessageType.TRANSACTION_ONCE);
		
		/** 获取该消息要触发的那台Server */
		String server = clientRemoting.acquireFireServer(messageList.get(0).getMessageKey());
		if(StringUtil.isBlank(server)) {
			return new SendResult(false, ResultCode.SERVER_ERROR, messageKeyValueList);
		}

		Result sendResult = null;
		try {
			InvocationContext.setConnectionChannel(new ConnectionChannel(server, ROLE_TYPE_PRODUCER, this.producerConfig.getProducerId()));
			sendResult = serverService.send(messageList);//发送半消息
		} catch (Throwable e) {
			logger.error("[DefaultTransactionProducer]: send message error, messageList:" + messageList, e);
		}
		
		if(null == sendResult) {
			return new SendResult(false, ResultCode.HALF_MESSAGE_ERROR, messageKeyValueList);//如果返回值是null那就是超时了
		}
		
		if(! sendResult.getData().booleanValue()) {
			return new SendResult(false, sendResult.getResultCode(), messageKeyValueList);//发送消息失败
		}
		
		//执行业务逻辑
		TransactionStatus transactionStatus = TransactionStatus.UnKnow;
		try {
			transactionStatus = localTransactionExecuter.execute(object);
		} catch (Throwable e) {
			logger.error("[DefaultTransactionProducer]: execute message error, messageList:" + messageList, e);
			transactionStatus = TransactionStatus.Rollback;
		}
		
		if(null == transactionStatus) {
			transactionStatus = TransactionStatus.UnKnow;//用户返回null 就不知道该干啥
		}
		
		switch(transactionStatus) {
		case UnKnow:
			
			return new SendResult(false, ResultCode.UNKNOW_TRANSACTION_STATUS_ERROR, messageKeyValueList);
		case Commit:
			
			//将消息设置为待发送状态
			MessageUtil.setMessageStatus(messageList, MessageStatus.READY_TO_FIRE);
			
			break ;
		case Rollback:
			
			//将消息设置为丢弃状态
			MessageUtil.setMessageStatus(messageList, MessageStatus.DISCARD);
			
			break ;
			default:
		}
		
		//发送确认消息
		Result updateResult = null;
		try {
			InvocationContext.setConnectionChannel(new ConnectionChannel(server, ROLE_TYPE_PRODUCER, this.producerConfig.getProducerId()));
			updateResult = serverService.update(messageList);
		} catch (Throwable e) {
			logger.error("[DefaultTransactionProducer]: confirm message error, messageList:" + messageList, e);
		}
		
		if(null == updateResult) {
			return new SendResult(false, ResultCode.CONFIRM_MESSAGE_TIMEOUT, messageKeyValueList);//如果返回值是null那就是超时了
		}
		
		return new SendResult(updateResult, messageKeyValueList);
	}

	/**
	 * 关闭
	 */
	public void shutdown() {
		
		//移除事务生产者
		TMQFactory.removeTransactionProducer(this.producerConfig.getProducerId(), null);
		
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy