微服务痛点-基于Dubbo + Seata的分布式事务(TCC模式) (4)

数据持久化操作逻辑修改:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="cn.mushuwei.account.dao.AccountDao"> <!-- 以下是tcc模式所需的数据库操作 --> <update> update tcc_account set amount = amount - #{amount}, frozen_amount = frozen_amount + #{amount} where user_id = #{userId} </update> <update> update tcc_account set frozen_amount = frozen_amount - #{amount} where user_id = #{userId} </update> <update> update tcc_account set amount = amount + #{amount}, frozen_amount = frozen_amount - #{amount} where user_id = #{userId} </update> </mapper> Order订单

数据库添加订单创建状态:

create table if not exists `order`.tcc_order ( id bigint auto_increment primary key, order_no varchar(100) null comment '订单号', user_id varchar(50) null comment '用户编号', code varchar(100) null comment '商品编码', count int null comment '商品数量', amount double(50,2) null comment '消费总金额', status tinyint null comment '状态,1-预创建;2-创建成功;3-创建失败' );

将原来的创建订单一步逻辑修改成两阶段逻辑操作:

package cn.mushuwei.order.api; import cn.mushuwei.order.api.dto.OrderDTO; import io.seata.rm.tcc.api.BusinessActionContext; import io.seata.rm.tcc.api.BusinessActionContextParameter; import io.seata.rm.tcc.api.LocalTCC; import io.seata.rm.tcc.api.TwoPhaseBusinessAction; /** * @author jamesmsw * @date 2020/12/1 5:57 下午 */ @LocalTCC public interface OrderApi { /** * 创建订单准备 * * @param orderDTO * @param actionContext 业务动作上下文 * @return */ @TwoPhaseBusinessAction(name = "createOrderTcc", commitMethod = "createOrderCommit", rollbackMethod = "createOrderCancel") Boolean createOrderPrepare(BusinessActionContext actionContext, @BusinessActionContextParameter(paramName = "orderDTO") OrderDTO orderDTO); /** * 创建订单提交 * * @param actionContext 业务动作上下文 * @return */ Boolean createOrderCommit(BusinessActionContext actionContext); /** * 创建订单取消 * * @param actionContext 业务动作上下文 * @return */ Boolean createOrderCancel(BusinessActionContext actionContext); }

TwoPhaseBusinessAction注解标记这是个TCC接口,同时指定commitMethod,rollbackMethod的名称BusinessActionContext是TCC事务中的上下文对象 BusinessActionContextParameter注解标记的参数会在上下文中传播,即能通过BusinessActionContext对象在commit方法及cancle方法中取到该参数值

RM 的接口上面必须要有@LocalTCC 注解,且必须在接口上面

数据持久化操作逻辑修改:

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="cn.mushuwei.order.dao.OrderDao"> <insert keyProperty="id" useGeneratedKeys="true" parameterType="cn.mushuwei.order.entity.OrderDO"> insert into `tcc_order` (order_no, user_id, code, count, amount, status) VALUES (#{order.orderNo}, #{order.userId}, #{order.code}, #{order.count}, #{order.amount}, #{order.status}) </insert> <update> update `tcc_order` set status = #{status} where order_no = #{orderNo} </update> </mapper> 演示 启动Dubbo、Seata、MySQ并初始化数据, 使各服务应用注册到Seata上

Dubbo、Seata和MySQL服务

mushuwei@mushuweideMacBook-Pro-2 seata % docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0c9c325a039c mysql:latest "docker-entrypoint.s…" 2 weeks ago Up 7 minutes 0.0.0.0:3306->3306/tcp, 33060/tcp mysql5.7 b8031fa865cd seataio/seata-server "java -Djava.securit…" 2 weeks ago Up 20 seconds 0.0.0.0:8091->8091/tcp seata_seata-server_1 2af927368a15 apache/dubbo-admin "java -XX:+UnlockExp…" 2 weeks ago Up 2 hours 0.0.0.0:8080->8080/tcp dubbo_admin_1 7afec07234c9 zookeeper "/docker-entrypoint.…" 2 weeks ago Up 2 hours 2888/tcp, 3888/tcp, 0.0.0.0:2181->2181/tcp, 8080/tcp dubbo_zookeeper_1

初始化数据

mysql> use storage; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> select * from tcc_storage; +----+----------------+------+-------+--------------+ | id | commodity_code | name | count | frozen_count | +----+----------------+------+-------+--------------+ | 1 | cola | ???? | 2000 | 0 | +----+----------------+------+-------+--------------+ 1 row in set (0.00 sec) mysql> use account; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> select * from tcc_account; +----+---------+---------+---------------+ | id | user_id | amount | frozen_amount | +----+---------+---------+---------------+ | 1 | user123 | 1250.00 | 0.00 | +----+---------+---------+---------------+ 1 row in set (0.00 sec) mysql> use order; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> select * from tcc_order; Empty set (0.00 sec)

启动Storage、Account、Order和Business

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpyzyx.html