The News of ROCKETMQ Things

Source: Internet
Author: User
Tags json message queue rollback

There are several common ways to solve distributed transactions:

1, the use of business rollback method:

For example:

	public void Updatebyprimarykey (pay record) throws Exception {
		 try {
			 //join in database made +100
			Paymapper.updatebyprimarykey (record);
			After the execution of the previous step, continue to go below, and another database to make changes, the result failed, then how to rollback
		} catch (Exception e) {
			e.printstacktrace ();
			Record an indication bit, if the first step has been performed successfully, then change back to
			Paymapper.updatebyprimarykey (record);}
	}
But this is going to cost a lot of code and error-prone.


2, the use of JTA for the management of distributed things do not do an example,


3, create intermediate system, colleague control database, avoid two application control two database, increase difficulty degree

4, use the final consistency message to manage distributed things.


Recommended today is Ali for Taobao tailored ROCKETMQ message queue, support things message, order consumption, batch consumption, support large concurrency, mass message.


Transaction message Principle implementation process:

One stage:
Producer sends 1 messages of type Transactionpreparedtype to the broker, the broker receives the message in Commitlog, and then returns the Queueoffset and MessageID of the message to producer , MessageID contains a commitlogoffset (that is, the message's offset in Commitlog, which can be directly located to the message itself), because the type of message is saved, Commitlogoffset is not saved to Consumerqueue, the client does not get commitlogoffset through consumerqueue, so the type of message cannot be taken, resulting in no consumption.

Phase of the process, the broker holds 1 messages.

Two stages:
The Transactionexecuterimpl on the producer side performs a local operation, returns the state of the local transaction, and then sends a type of Transactioncommittype or Transactionrollbacktype message to broker to confirm the commit or rollback, broker through the Commitlogoffset in request, Gets the message with the status Transactionpreparedtype above (message a), and then reconstructs a message b with the same content as message A. Set the status to Transactioncommittype or Transactionrollbacktype, and then save. Where the Transactioncommittype type, will be put Commitlogoffset to Consumerqueue, Transactionrollbacktype type, the message body is set to empty, Will not put Commitlogoffset into the consumerqueue.


Send a thing message:

	Private final String group_name = "Transaction-pay";
	Private final String namesrv_addr = "192.168.68.129:9876";
	
	Private Transactionmqproducer producer;
		Public Mqproducer () {this.producer = new transactionmqproducer (group_name);	THIS.PRODUCER.SETNAMESRVADDR (NAMESRV_ADDR);	NameServer Service This.producer.setCheckThreadPoolMinSize (5);	Transaction rollback minimum concurrency number this.producer.setCheckThreadPoolMaxSize (20);	Transaction callback Max concurrency number This.producer.setCheckRequestHoldMax (2000); Number of queues//server callback producer, check for local transaction branch success or failure This.producer.setTransactionCheckListener (new Transactionchecklistener () {PU Blic localtransactionstate checklocaltransactionstate (messageext msg) {System.out.println ("state--" + New String (msg
				. GetBody ()));
			return localtransactionstate.commit_message;
		}
		});
		try {this.producer.start ();
		} catch (Mqclientexception e) {e.printstacktrace ();
		}} public QueryResult Querymessage (string topic, string key, int maxnum, long begin, long end) throws Exception {return This.producer.queryMessage (topic, key, Maxnum, begin, end); } public localtransactionstate Check (messageext me) {localtransactionstate ls = this.producer.getTransactionCheckList
		Ener (). Checklocaltransactionstate (Me);
	return LS; The public void sendtransactionmessage (Message message, Localtransactionexecuter Localtransactionexecuter, map< String, object> Transactionmapargs) throws Exception {Transactionsendresult TSR = This.producer.sendMessageInTransa
		ction (Message, Localtransactionexecuter, Transactionmapargs);
	SYSTEM.OUT.PRINTLN ("Send return Content:" + tsr.tostring ());
				public void shutdown () {runtime.getruntime (). Addshutdownhook (New Thread (new Runnable () {public void run () {
			Producer.shutdown ();
		}
		}));
	System.exit (0); }
Consume Things news:


public void Querymessage (String topic) throws mqclientexception{consumer = new Defaultmqpushconsumer (group_name);  
        CONSUMER.SETNAMESRVADDR (NAMESRV_ADDR);  
        Consumer.setconsumemessagebatchmaxsize (10);  
        /** * Set consumer whether the first boot starts from the head of the queue or the end of the queue consumption <br> * If it is not the first time, then continue to spend in the last place of consumption * *  
  
        Consumer.setconsumefromwhere (Consumefromwhere.consume_from_first_offset);  
  
        Consumer.subscribe (Topic, "*"); Consumer.registermessagelistener (New messagelistenerconcurrently () {public consumeconcurrentlystatus con  
  
                    Sumemessage (list<messageext> msgs, Consumeconcurrentlycontext context) {try { for (Messageext msg:msgs) {System.out.println (msg + ", Content:" + new String (Msg.getbody (  
                    )));  
  
                    }} catch (Exception e) {e.printstacktrace (); Return Consumeconcurrentlystatus.reconsume_later;//Retry} return Consumeconcurrentlystatu  
  
        s.consume_success;//success});  
  
        Consumer.start ();    
	System.out.println ("Transaction_consumer Started.");
 }

Local thing execution:

Package bhz.mq;

Import Java.util.Map;
Import org.springframework.beans.factory.annotation.Autowired;

Import org.springframework.stereotype.Component;
Import Bhz.entity.Pay;
Import Bhz.service.PayService;
Import Com.alibaba.fastjson.JSON;
Import Com.alibaba.fastjson.JSONObject;
Import Com.alibaba.rocketmq.client.producer.LocalTransactionExecuter;
Import Com.alibaba.rocketmq.client.producer.LocalTransactionState;


Import Com.alibaba.rocketmq.common.message.Message; /** * Execute local transaction, callback by client/* @Component public class Transactionexecuterimpl implements Localtransactionexecuter {@Autow
	
	ired private Payservice Payservice; Public localtransactionstate Executelocaltransactionbranch (Message msg, Object Arg) {try {//message Body String
			A=new String (Msg.getbody (), "utf-8");
			Jsonobject MessageBody = Json.parseobject (a); Transaction Mapargs//--------------------in PUT----------------------//SYSTEM.OUT.PRINTLN ("message body =" +
			MessageBody); System.out.prinTLN ("message tag =" + Msg.gettags ()); --------------------in PUT----------------------////userid Integer UserID = Messagebody.getinteger ("userid"
			);
			Money Double-Money =double.parsedouble (messagebody.getstring ("money"));
			Mode String Pay_mode = messagebody.getstring ("Pay_mode");
			Pay//pay pay = Payservice.selectbyprimarykey (userid);
			Persistent data pay pay=new pay ();
			Pay.setamount (11.2);
			Pay.setuserid (1);
			Payservice.updateamount (Pay, pay_mode, money);
			
		Successfully notifies MQ message change that the message changed to:< acknowledgment send > Return localtransactionstate.commit_message;
			} catch (Exception e) {e.printstacktrace ();
			
		Failure does not notify MQ that the message has been in:< pending send > Return localtransactionstate.rollback_message; }
		
	}
}

Client callbacks:

Package bhz.mq;

Import Java.util.concurrent.atomic.AtomicInteger;
Import Com.alibaba.rocketmq.client.producer.LocalTransactionState;
Import Com.alibaba.rocketmq.client.producer.TransactionCheckListener;

Import Com.alibaba.rocketmq.common.message.MessageExt; public class Transactionchecklistenerimpl implements transactionchecklistener{private Atomicinteger Transactionindex
	 
	 
    = new Atomicinteger (0);  @Override public localtransactionstate checklocaltransactionstate (Messageext msg) {System.out.println ("server
 
        Checking trmsg "+ msg.tostring ());
        int value = Transactionindex.getandincrement ();
        if (value% 6) = = 0) {throw new RuntimeException ("Could not find db");
        } else if ((value% 5) = = 0) {return localtransactionstate.rollback_message;
        } else if ((value% 4) = = 0) {return localtransactionstate.commit_message;
    } return Localtransactionstate.unknow;
}
} 

The order of ROCKETMQ and Filer will be analyzed in the next article.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.