当前位置: 首页 > news >正文

西宁网站建设君博推荐python做网站 知乎

西宁网站建设君博推荐,python做网站 知乎,有价值 网站,十大黑心装修公司现有seata、tcc-transaction等tcc框架实现都较为重量级#xff0c;今天主要带来一种轻量级的实现#xff0c;大概只用了1200行代码实现。不依赖具体框架grpc、http、dubbo等#xff0c;只需要业务系统按照标准化实现Try、Commit、Cancel实现接口即可。 已解决悬挂、幂等、空…现有seata、tcc-transaction等tcc框架实现都较为重量级今天主要带来一种轻量级的实现大概只用了1200行代码实现。不依赖具体框架grpc、http、dubbo等只需要业务系统按照标准化实现Try、Commit、Cancel实现接口即可。 已解决悬挂、幂等、空回滚、事务嵌套问题业务层面无需关注这部分处理。 TCC分为以下几个阶段 执行前置动作 (业务资源的初始化例如: 创建一个初始化的订单)Try (调用外部服务进行资源的预留)执行本地事务 (需要保证业务是在一个事务内完成)Commit\Cancel (根据本地事务的执行的成功与否进行commit || cancel) 示例 该示例主要用于用户下单的同时需要扣减用户积分的场景订单服务和积分服务分别是独立服务部署它们之间存在分布式事务的问题 我们通过当前框架展示是如何解决以上问题的。 tcc/src/test/java/com/damon/sample at master · 654894017/tcc · GitHub 步骤1.初始化订单服务数据库表 -- 创建事务表 CREATE TABLE tcc_main_log_order (biz_id bigint NOT NULL COMMENT 业务id,status int NOT NULL DEFAULT 0 COMMENT 状态: 1 创建事务成功 2 回滚成功 3 完成本地事务成功 4 提交事务成功,version int NOT NULL DEFAULT 0 COMMENT 版本号,last_update_time bigint NOT NULL DEFAULT 0 COMMENT 最后更新时间,create_time bigint NOT NULL DEFAULT 0 COMMENT 创建时间,checked_times int NOT NULL DEFAULT 0 COMMENT 失败检查次数,PRIMARY KEY (biz_id),KEY idx_status_checked_times_create_time (status,checked_times,create_time) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_bin COMMENT主事务日志表;-- 创建订单表 CREATE TABLE tcc_demo_order (order_id bigint NOT NULL,status int NOT NULL,user_id bigint NOT NULL,deduction_points bigint DEFAULT NULL,PRIMARY KEY (order_id) USING BTREE ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_bin; 步骤2.积分服务创建子事务表 -- 创建子事务表 CREATE TABLE tcc_sub_log_order (biz_id bigint NOT NULL COMMENT 业务id,sub_biz_id bigint NOT NULL DEFAULT 0 COMMENT 子业务id,status int NOT NULL DEFAULT 0 COMMENT 状态: 1 创建事务成功 2 提交事务成功 3 回滚事务成功,version int NOT NULL DEFAULT 0 COMMENT 版本号,last_update_time bigint NOT NULL DEFAULT 0 COMMENT 最后更新时间,create_time bigint NOT NULL DEFAULT 0 COMMENT 创建时间,PRIMARY KEY (biz_id,sub_biz_id) USING BTREE ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_bin COMMENT子事务日志表;-- 创建积分变动日志表 CREATE TABLE tcc_demo_points_changing_log (biz_id bigint NOT NULL,user_id bigint NOT NULL,change_points bigint NOT NULL,change_type int NOT NULL,status int NOT NULL,PRIMARY KEY (biz_id) USING BTREE ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_bin;-- 创建用户积分表 CREATE TABLE tcc_demo_user_points (user_id bigint NOT NULL,points bigint NOT NULL,PRIMARY KEY (user_id) USING BTREE ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_bin;-- 初始化用户积分 INSERT INTO tcc_demo_user_points (user_id, points) VALUES (12345678, 999999999989989999); 注意事项 事务表都是以tcc_main_log_xxxx 命名,子事务表都是以tcc_sub_log_xxxx命名,xxxx为业务分类,例如订单下单的业务,事务表命名为tcc_main_log_order, 子事务表命名为tcc_sub_log_order. 步骤3.运行 com.damon.sample.points.PointsApplication 步骤4.运行 com.damon.sample.order.TestRun 下单服务 下单服务继承TccMainService服务 package com.damon.sample.order.app;import cn.hutool.core.util.IdUtil; import com.damon.sample.order.client.IOrderSubmitAppService; import com.damon.sample.order.domain.IPointsGateway; import com.damon.sample.order.domain.Order; import com.damon.tcc.TccMainService; import com.damon.tcc.config.TccMainConfig; import com.damon.tcc.exception.TccLocalTransactionException; import com.damon.tcc.exception.TccPrepareException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service;import java.util.HashMap; import java.util.Map;Service public class OrderSubmitAppService extends TccMainServiceLong, MapString, Boolean, Order implements IOrderSubmitAppService {private final JdbcTemplate jdbcTemplate;private final IPointsGateway pointsGateway;Autowiredpublic OrderSubmitAppService(TccMainConfig config, IPointsGateway pointsGateway) {super(config);this.jdbcTemplate new JdbcTemplate(config.getDataSource());this.pointsGateway pointsGateway;}/*** 检查失败的日志用于纠正事务是否需要回顾还是提交*/public void executeFailedLogCheck() {super.executeFailedLogCheck();}/*** 检查死亡的日志用于纠正事务是否需要回顾还是提交*/public void executeDeadLogCheck() {super.executeDeadLogCheck();}/*** 执行失败日志检查的时候需要回查请求参数因为事务日志未记录方法请求参数所以需要回查一下** param bizId 实体对象id业务id* return*/Overrideprotected Order callbackParameter(Long bizId) {return jdbcTemplate.queryForObject(select * from tcc_demo_order where order_id ? , new BeanPropertyRowMapper(Order.class), bizId);}/*** 创建订单 1 预先创建订单 2 执行try动作** param userId* param points* return*/Overridepublic Long submitOrder(Long userId, Long points) {Long orderId IdUtil.getSnowflakeNextId();// 预创建订单jdbcTemplate.update(insert into tcc_demo_order(order_id, user_id, status, deduction_points) values (?, ?, ? ,? ),orderId, userId, 0, points);Order order new Order(orderId, 0, userId, points);try {return super.process(order);} catch (TccPrepareException e) {throw e;} catch (TccLocalTransactionException e) {throw e;} catch (Exception e) {throw new RuntimeException(系统异常);}}/*** try执行用户积分扣除** param order* return*/Overrideprotected MapString, Boolean prepare(Order order) {Boolean result pointsGateway.tryDeductionPoints(order.getOrderId(), order.getUserId(), order.getDeductionPoints());MapString, Boolean map new HashMap();map.put(flag, result);return map;}Overrideprotected Long executeLocalTransaction(Order object, MapString, Boolean map) {int result jdbcTemplate.update(update tcc_demo_order set status ? where order_id ? , 1, object.getOrderId());if (result 0) {throw new RuntimeException(无效的订单id : object.getOrderId());}return object.getOrderId();}/*** commit积分** param order*/Overrideprotected void commit(Order order) {pointsGateway.commitDeductionPoints(order.getOrderId(), order.getUserId(), order.getDeductionPoints());}/*** cancel回滚积分** param order*/Overrideprotected void cancel(Order order) {pointsGateway.cancelDeductionPoints(order.getOrderId(), order.getUserId(), order.getDeductionPoints());} }积分服务 积分服务继承TccSubService服务 package com.damon.sample.points.app;import com.damon.sample.points.client.IPointsDeductionAppService; import com.damon.sample.points.client.PointsDeductCmd; import com.damon.tcc.config.TccSubConfig; import com.damon.tcc.TccSubService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.support.TransactionSynchronizationManager;Service public class PointsDeductionAppService extends TccSubServiceBoolean, PointsDeductCmd implements IPointsDeductionAppService {private final Logger log LoggerFactory.getLogger(PointsDeductionAppService.class);private final JdbcTemplate jdbcTemplate;Autowiredpublic PointsDeductionAppService(TccSubConfig config) {super(config);this.jdbcTemplate new JdbcTemplate(config.getDataSource());}/*** try执行积分扣减* param parameter* return*/Overridepublic boolean attempt(PointsDeductCmd parameter) {return super.prepare(parameter, cmd - {int result jdbcTemplate.update(update tcc_demo_user_points set points points - ? where user_id ? and points - ? 0,cmd.getDeductionPoints(), cmd.getUserId(), cmd.getDeductionPoints());boolean transactionActive TransactionSynchronizationManager.isActualTransactionActive();if (result 0) {throw new RuntimeException(用户积分不足 || 用户不存在);}int result2 jdbcTemplate.update(insert tcc_demo_points_changing_Log (user_id, change_points, change_type, biz_id, status) values(?,?,?,?,?),cmd.getUserId(), cmd.getDeductionPoints(), 1, cmd.getOrderId(), 0);return true;});}/*** commit提交积分扣减* param parameter*/Overridepublic void commit(PointsDeductCmd parameter) {super.commit(parameter, cmd - {int result jdbcTemplate.update(update tcc_demo_points_changing_Log set status 1 where biz_id ?, cmd.getBizId());if (result 0) {throw new RuntimeException(无效的业务id无法积分commit);}});}/*** cancel回滚积分扣减* param parameter*/Overridepublic void cancel(PointsDeductCmd parameter) {super.cancel(parameter, cmd - {int result jdbcTemplate.update(update tcc_demo_points_changing_Log set status 2 where biz_id ?, cmd.getBizId());if (result 0) {log.error(无效的业务id : {}无法进行积分cancel, cmd.getBizId());return;}int result2 jdbcTemplate.update(update tcc_demo_user_points set points points ? where user_id ?,cmd.getDeductionPoints(), cmd.getUserId());if (result2 0) {throw new RuntimeException(无效的用户id无法进行积分rollback);}});}}FAQ 1.关于幂等、悬挂、空回滚如何解决 主要基于执行先判断的思路来实现的在子系统执行Cancle的时候都会先判断tcc_sub_log_xxxx这个表的事务事务已经完成或者取消如果已完成直接不执行业务如果未执行则执行Cancel业务同时更新tcc_sub_log_xxxx的日志状态为已取消。最极端情况举一个示例假如服务提供者try和cancel同时在执行try因为网络问题非常滞后的到达业务服务器这时主服务因为等待超时调用了子服务cancel动作。主要分两种情况 1.假如先执行了cancel在执行Try则不会执行因为子事务已经取消tcc_sub_log_xxxx会增加一条取消日志在执行try操作时会出现索引冲突异常tcc_sub_log_xxxx表有biz_id sub_biz_id唯一索引子事务的try会回滚。 2.假如先执行了try在执行cancel则会执行正常取消属于正常情况。还一种情况就是同时执行了Try、cancel操作这时候只能依赖tcc_sub_log_xxxx表有biz_id sub_biz_id唯一索引来解决更新冲突问题。假如Try先执行cacel就会报错上游服务重新发起cancel即可。假如先执行了cancle则try会报错唯一索引冲突这时不用处理子事务的try会回滚。 2.tcc_sub_log_xxxx表事务需要和本地业务在一个数据库事务 是的幂等、悬挂、空回滚问题都是基于tcc_sub_log_xxxx的事务日志表进行的需要保证业务事务和tcc_sub_log_xxxx表的事务在一个数据库事务下。 3.上游系统重放try、commit、cancel怎么处理 调用方误触发存在以下几种可能 1.已经commit的事务调用了cancle已增加事务是否已commit判断已commit的事务调用cancel不会执行同时需要基于tcc_sub_log_xxxx表的version实现的乐观锁来解决更新冲突的问题。 2.已cancel的事务调用了commit已增加事务是否已cancel判断已cancel的事务调用coommit不会执行同时需要基于tcc_sub_log_xxxx表的version实现的乐观锁来解决更新冲突的问题。 3.已cancel的事务调用了try依赖tcc_sub_log_xxxx表biz_id sub_biz_id唯一索引来解决更新冲突问题。 4.已commit的事务调用了try依赖tcc_sub_log_xxxx表biz_id sub_biz_id唯一索引来解决更新冲突问题。 5.重复try依赖tcc_sub_log_xxxx表biz_id sub_biz_id唯一索引来解决更新冲突问题。 6.重复commit已增加事务是否已commit判断已commit的事务调用commit不会执行同时需要基于tcc_sub_log_xxxx表的version实现的乐观锁来解决更新冲突的问题。 7.重复cancel已增加事务是否已cancel判断已cancel的事务调用cancel不会执行同时需要基于tcc_sub_log_xxxx表的version实现的乐观锁来解决更新冲突的问题。 GitHub - 654894017/tcc: 编程式tcc框架已解决悬挂、幂等、空回滚、事务嵌套问题。
http://www.dnsts.com.cn/news/276246.html

相关文章:

  • 分类信息网站建设系统建设网站困难的解决办法
  • 网站虚拟主机网站面包屑导航
  • 农产品电商网站建设主要工作信息服务平台是什么
  • wordpress 文字省略短视频seo是什么
  • 用vps刷网站流量要怎么做服装网站推广计划书范文500字
  • 高端装饰公司网站设计wordpress的pingsu主题
  • 上海闵行区邮编seo网站怎么优化
  • 网站一般多长时间北京建设厅官方网站
  • 名医工作室 网站建设十大室内设计师排名
  • dw建设网站如何加入音乐在线设计平台的优缺点
  • 中国网站建设公司图片企业邮箱注册申请费用
  • 织梦做的网站用什么数据库网站功能与内容设计的步骤
  • 做设计太依赖网站素材网站负责人照片
  • 免费的个人主页网页制作网站wordpress 前台用户
  • 网站开发swf素材公司想建个网站
  • .win域名做网站怎么样常州建设局考试网站
  • 简易网站的html代码网页设计与网站建设课程设计
  • 电商网站建设建站方案做衣服的网站推荐
  • 会网站建设怎样赚钱wordpress办公插件
  • 网站要求wordpress商城县属于哪个市
  • 快速建立平台网站开发aspcms网站使用教程
  • 游戏网站策划网站建设制作免费咨询
  • 企业网站建设方案如何西安网站优化排名案例
  • 手机p2p网站建设wordpress负载均衡上传附件
  • 网站建设技术架构和语言网站建设中源码编程同样重要
  • 高级网站建设费用泉州住房城乡建设局网站
  • 四川广汇建设有限公司网站昆明做网站哪家公司好
  • 西昌市做网站的公司上海app开发定制公司
  • 电子商务网站建设新闻怎么分析一个网站
  • 网站建设毕业设计总结环保行业网站建设