java110
2020-07-06 b58df982bda78124dd785f595a5519cb88b7d3a9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
package com.java110.core.factory;
 
import com.alibaba.fastjson.JSONObject;
import com.java110.dto.order.OrderDto;
import com.java110.utils.constant.ServiceConstant;
import com.java110.utils.factory.ApplicationContextFactory;
import com.java110.utils.util.StringUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.HttpStatusCodeException;
import org.springframework.web.client.RestTemplate;
 
import java.util.HashMap;
import java.util.Map;
 
/**
 * @ClassName Java110TransactionalFactory
 * @Description TODO
 * @Author wuxw
 * @Date 2020/7/3 22:30
 * @Version 1.0
 * add by wuxw 2020/7/3
 **/
public class Java110TransactionalFactory {
 
    private static Logger logger = LoggerFactory.getLogger(Java110TransactionalFactory.class);
 
    //订单服务
    private static final String URL_API = ServiceConstant.SERVICE_ORDER_URL + "/order/oIdApi";
 
    /**
     * 创建事务ID
     */
    private static final String CREATE_O_ID = URL_API + "/createOId";
 
    /**
     * 回退事务ID
     */
    private static final String FALLBACK_O_ID = URL_API + "/fallBackOId";
 
 
    //全局事务ID
    public static final String O_ID = "O-ID";
 
    //当前服务ID
    public static final String SERVICE_ID = "SERVICE-ID";
 
    private static ThreadLocal<Map<String, String>> threadLocal = new ThreadLocal<Map<String, String>>() {
        @Override
        protected Map<String, String> initialValue() {
            return new HashMap<String, String>();
        }
    };
 
    public static String put(String key, String value) {
        return threadLocal.get().put(key, value);
    }
 
    public static String get(String key) {
        return threadLocal.get().get(key);
    }
 
    public static String remove(String key) {
        return threadLocal.get().remove(key);
    }
 
    public static Map<String, String> entries() {
        return threadLocal.get();
    }
 
    public static String getOrCreateOId(OrderDto orderDto) {
        //全局事务开启者
        if (StringUtils.isEmpty(orderDto.getoId())) {
            createOId(orderDto);
        }
        String oId = get(O_ID);
        return oId;
    }
 
    /**
     * 获取事务ID
     *
     * @return
     */
    public static String getOId() {
        String oId = get(O_ID);
        return oId;
    }
 
    /**
     * 创建事务
     *
     * @param orderDto
     */
    private static void createOId(OrderDto orderDto) {
        RestTemplate restTemplate = ApplicationContextFactory.getBean("restTemplate", RestTemplate.class);
        HttpHeaders header = new HttpHeaders();
        HttpEntity<String> httpEntity = new HttpEntity<String>(JSONObject.toJSONString(orderDto), header);
        ResponseEntity<String> responseEntity = null;
        try {
            responseEntity = restTemplate.exchange(CREATE_O_ID, HttpMethod.POST, httpEntity, String.class);
        } catch (HttpStatusCodeException e) { //这里spring 框架 在4XX 或 5XX 时抛出 HttpServerErrorException 异常,需要重新封装一下
            responseEntity = new ResponseEntity<String>(e.getResponseBodyAsString(), e.getStatusCode());
        } catch (Exception e) {
            responseEntity = new ResponseEntity<String>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
        } finally {
            logger.debug("请求地址为,{} 请求订单服务信息,{},订单服务返回信息,{}", CREATE_O_ID, httpEntity, responseEntity);
        }
        if (responseEntity.getStatusCode() != HttpStatus.OK) {
            throw new IllegalArgumentException("创建事务失败" + responseEntity.getBody());
        }
        JSONObject order = JSONObject.parseObject(responseEntity.getBody());
 
        if (!order.containsKey("oId") || StringUtils.isEmpty(order.getString("oId"))) {
            throw new IllegalArgumentException("创建事务失败" + responseEntity.getBody());
        }
        orderDto.setoId(order.getString("oId"));
        //将事务ID 存放起来
        put(O_ID, orderDto.getoId());
    }
 
    /**
     * 处理失败,回退事务
     */
    public static void fallbackOId() {
        String oId = getOId();
        if (StringUtil.isEmpty(oId)) {
            //当前没有开启事务无需回退
            logger.debug("当前没有开启事务无需回退");
            return;
        }
        OrderDto orderDto = new OrderDto();
        orderDto.setoId(oId);
        RestTemplate restTemplate = ApplicationContextFactory.getBean("restTemplate", RestTemplate.class);
        HttpHeaders header = new HttpHeaders();
        HttpEntity<String> httpEntity = new HttpEntity<String>(JSONObject.toJSONString(orderDto), header);
        ResponseEntity<String> responseEntity = null;
        try {
            responseEntity = restTemplate.exchange(FALLBACK_O_ID, HttpMethod.POST, httpEntity, String.class);
        } catch (HttpStatusCodeException e) { //这里spring 框架 在4XX 或 5XX 时抛出 HttpServerErrorException 异常,需要重新封装一下
            responseEntity = new ResponseEntity<String>(e.getResponseBodyAsString(), e.getStatusCode());
        } catch (Exception e) {
            responseEntity = new ResponseEntity<String>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
        } finally {
            logger.debug("回退事务 请求地址为,{} 请求订单服务信息,{},订单服务返回信息,{}", FALLBACK_O_ID, httpEntity, responseEntity);
        }
 
        if (responseEntity.getStatusCode() == HttpStatus.NOT_FOUND) {
            //当前没有开启事务无需回退
            logger.debug("当前没有开启事务无需回退");
            return;
        }
 
        if (responseEntity.getStatusCode() == HttpStatus.BAD_REQUEST) {
            throw new IllegalArgumentException("回退事务失败" + responseEntity.getBody());
        }
 
    }
}