There is a business scenario, the business data audit through the need to send a text message to the user, the text message process is more time-consuming, may take a few seconds or even more than 10 seconds, so the use of asynchronous texting
Annotated @async is used to implement:
1.SpringApplication Enable annotations @enableasync
@SpringBootApplication @importresource (locations = {"Classpath:/spring/spring-*.xml"}) @ Enabletransactionmanagement (proxytargetclass=true) @EnableScheduling @enableautoconfiguration (exclude = { Freemarkerautoconfiguration.class}) @EnableSwagger2 @servletcomponentscan (basepackages= "com.xx") @ Enablemongorepositories (basepackages = "com.xx.xx.xx.xx") @EnableAsyncpublic class Iemsapplication {public static void Main (string[] args) {Springapplication.run (iemsapplication.class, args);} ...
2. Add a comment on the business layer (@Service) specific audit method @async
@Asyncpublic void Cancelaudit (defectform defectform) {map<string,object> params = new hashmap<> (); Params.put ("Defectid", Defectform.getdefectid ()); Defect record Idparams.put ("Defectstatus", 3); Update defect record status audit reject Params.put ("Reason", Defectform.getreason ()); Refusal reason defectrecorddao.updatebyprimarykeyselective (params);
//above is business processing, below is textingAudit refused to send text messages, text messages sent to the defect escalation, defect content, audit rejection reason account account = Accountdao.findaccountbyid (XXX); if (account! = NULL && Stringutils.isnotblank (Account.getmobile ())) {String mobile = Account.getmobile (); String defectcontent = Defectform.getdefectcontent (); String reason = Defectform.getreason (); map<string,string> TemplateData = new hashmap<> () templatedata.put ("Defectcontent", defectContent); Templatedata.put ("Reason", reason); Smsservice.sendsms (null, Mobile, Smsconstant.defect_refusrd_code, TemplateData, FALSE); Logger.debug ("Defect escalation record audit refused, send SMS to bug record escalation person ******");}}
3. Front-end Logic:
/** * Audit Reject, OK * @returns */function makerefuse () {var reason = $ ("#refuse_reason"). Val (); if (Reason==null | | Reason.trim () = = "") {Apputils.showtooltip ("Please fill in the rejection reason!") ", false); return;} var curdefect = Recordsjson[xxx];$.ajax ({url:path + '/xxx/xxx/qqq/cancelaudit ', type: ' Post ', DataType: ' JSON ', data: Curdefect,success:function (data) {if (data== "OK") {Apputils.showtooltip ("Audit rejected successfully! ", true); $ (" #topForm "). attr (" action ", Path + '/xxx/xxx/xxx '); $ (" #topForm "). Submit ();}});}
4.Controller Layer
@RequestMapping ("/xxx/xxx/cancelaudit") @ResponseBodypublic String cancelaudit (defectform defectform) { Defectrecordservice.cancelaudit (defectform); return "OK";}
Tested to update and send text messages asynchronously
However, found a serious problem: the front page click on the cancellation of the review page status occasionally can be refreshed, occasionally or before the state, re-query once, the page appears normal
Parsing code:Controller Layer Code write problem, controller layer call service layer (Defectrecordservice.cancelaudit (defectform);), Service Layer Cancelaudit (Defectform defectform) method The whole is @async,
The main thread is returned directly, while the city threads handle the logic of the service layer. So Ajax back to the foreground, the foreground to refresh the data, it may be City thread service update logic has not been processed, which caused the page refresh status error problem
In fact: What we expect is that the business logic (update operation) is completed and then returned; the entire business logic (update operation completed, returned) and texting asynchronous
The Modified code:
1.Controller Layer
@RequestMapping ("/xxx/xxx/cancelaudit") @ResponseBodypublic String cancelaudit (defectform defectform) { Defectrecordservice.cancelaudit (Defectform); update operation, after success down, Sendcancelauditmsg will start a new thread processing, the main thread continues to go down, go to return "OK";
Audit reject: Send SMS Defectrecordservice.sendcancelauditmsg (defectform) after business operation is completed; return "OK";}
2.Service Layer
Here we don't need to add asynchronous annotations public void Cancelaudit (Defectform defectform) {map<string,object> params = new hashmap<> ();p arams.put ("Defectid", Defectform.getdefectid ()); Defect record Idparams.put ("Defectstatus", 3); Update defect record status audit reject Params.put ("Reason", Defectform.getreason ()); Reason for refusal defectrecorddao.updatebyprimarykeyselective (params);}
take out the logic of texting, a single method, using asynchronous annotations @Asyncpublic void sendcancelauditmsg (Defectform defectform) {//Audit reject SMS, SMS sent to the defect escalation person, defect content, audit rejection reason account account = Accountdao.findaccountbyid (Defectform.getcreatoruserid ()); Null && Stringutils.isnotblank (Account.getmobile ())) {String mobile = Account.getmobile (); String defectcontent = Defectform.getdefectcontent (); String reason = Defectform.getreason (); map<string,string> TemplateData = new hashmap<> () templatedata.put ("Defectcontent", defectContent); Templatedata.put ("Reason", reason); Smsservice.sendsms (null, Mobile, Smsconstant.defect_refusrd_code, TemplateData, FALSE); Logger.debug ("Defect escalation record audit refused, send SMS to bug record escalation person ******");}}
This solves the problem, write a blog to mark
Springboot @Async Asynchronous processing of business logic and texting logic