@@ -198,6 +198,75 @@ store {
198198> 测试事务回滚成功场景:http://127.0.0.1:8084/api/business/purchase/rollback
199199
200200
201+ ##### 5. Seata-AT模式实战:因篇幅有限,只对核心代码进行说明
202+
203+ ###### 5.1 在所有分支事务设置全局事务XID:Seata的事务上下文由RootContext来管理。应用开启全局事务后,所有的分支事务都必须绑定这个全局的XID。当事务结束(提交或回滚完成),RootContext会自动解绑XID。另外RootContext是基于ThreadLocal线程安全的。(本次测试是在SpringBoot使用的是HTTP方式,所以才需要通过HTTP过滤器手动进行绑定XID。如果是Dubbo或SpringCloud环境,则框架层自动绑定)
204+
205+ ``` java
206+ @Component
207+ public class SeataFilter implements Filter {
208+
209+ @Override
210+ public void init (FilterConfig filterConfig ) throws ServletException {
211+ }
212+
213+ @Override
214+ public void doFilter (ServletRequest servletRequest , ServletResponse servletResponse , FilterChain filterChain ) throws IOException , ServletException {
215+ HttpServletRequest req = (HttpServletRequest ) servletRequest;
216+ String xid = req. getHeader(RootContext . KEY_XID. toLowerCase());
217+ boolean isBind = false ;
218+ if (StringUtils . isNotBlank(xid)) {
219+ // 绑定全局事务XID(Global Transaction)
220+ RootContext . bind(xid);
221+ isBind = true ;
222+ }
223+ try {
224+ filterChain. doFilter(servletRequest, servletResponse);
225+ } finally {
226+ if (isBind) {
227+ RootContext . unbind();
228+ }
229+ }
230+ }
231+
232+ @Override
233+ public void destroy () {
234+ }
235+ }
236+ ```
237+
238+ ###### 5.2 开启AT全局事务:在Seata中AT模式和TCC模式一样,业务方需要使用@GlobalTransactional 注解来开启全局事务(Global Transaction),会初始化GlobalTransactionInterceptor拦截器,开启一个全局事务,获取全局的事务ID(即RootContext.getXID())
239+
240+ ``` java
241+ @Service
242+ @RequiredArgsConstructor (onConstructor_ = {@Autowired (required = false )})
243+ public class BusinessService {
244+
245+ private static final Logger LOGGER = LoggerFactory . getLogger(BusinessService . class);
246+
247+ private final StorageClient storageClient;
248+
249+ private final OrderClient orderClient;
250+
251+ /**
252+ * 开启分布式全局事务,完成(减库存,下订单)操作
253+ *
254+ * @param userId
255+ * @param commodityCode
256+ * @param orderCount
257+ */
258+ @GlobalTransactional
259+ @SneakyThrows
260+ public void purchase (String userId , String commodityCode , int orderCount ) {
261+ LOGGER . info(" purchase begin ... xid: " + RootContext . getXID());
262+ storageClient. deduct(commodityCode, orderCount);
263+ orderClient. create(userId, commodityCode, orderCount);
264+ }
265+ }
266+
267+ ```
268+
269+
201270------------
202271
203272
0 commit comments