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

广州商务网站建设电话wordpress 极简 文字

广州商务网站建设电话,wordpress 极简 文字,深圳传媒公司,wordpress 商家 用户写在前面 前段时间,有同学反馈的一个面试问题,觉得分布式事务有点偏了,但其实也不算偏了,在java领域就有很火很成熟的seata分布式事务框架(阿里和蚂蚁的同学主导,目前在apache孵化)。 之前我们讲过了两阶段提交、三阶…

写在前面

前段时间,有同学反馈的一个面试问题,觉得分布式事务有点偏了,但其实也不算偏了,在java领域就有很火很成熟的seata分布式事务框架(阿里和蚂蚁的同学主导,目前在apache孵化)。
在这里插入图片描述
之前我们讲过了两阶段提交、三阶段提交(感兴趣可以翻翻历史文章),这篇文章我们就来讲讲TCC分布式事务 两提交阶段的变种,并用go语言简单实现一个TCC。详细代码在 https://github.com/CocaineCong/BiliBili-Code

原理介绍

TCC 分别代表:

  • Try:主要是对业务系统做检测及资源预留
  • Confirm:主要是对业务系统做确认提交,Try 阶段执行成功并开始执行 Confirm 阶段时,默认 Confirm 阶段是不会出错的
  • Cancel:主要是在业务执行错误,需要回滚的状态下执行的业务取消,释放预留资源

Try阶段完成业务的准备工作,Confirm阶段完成业务的提交,Cancel阶段完成事务的回滚。 基本原理如下图所示。

在这里插入图片描述

  1. 事务开始时,上层业务应用会向事务协调器注册启动事务。
  2. 业务应用会调用所有服务的Try接口,完成一阶段准备
  3. 接着业务应用调用事务协调器进行提交或者回滚事务。
  4. 事务协调器会根据Try接口返回情况,决定调用Confirm或者Cancel。如果接口调用失败,会进行重试

举个例子

我们就举一个电商平台的业务作为例子,当我们下单的时候,Try阶段需要检查以下:

  1. 检查当前账户的金额是否充足,并预留对应的金额来扣除
  2. 检查当前商品库存是否正常,并预留对应的库存
  3. 检查当前商品和当前账户的订单能否创建成功
    在这里插入图片描述

当我们Try阶段都执行成功之后,注意我们只是Try,做尝试,而不是真正的执行,就开始执行Confirm阶段:

  1. 减去对应的余额
  2. 减去库存
  3. 创建订单
    在这里插入图片描述

但如果我们Try阶段没成功,比如库存不足,或者余额不足,就开始执行Cancel阶段,因为我们Try虽然没有真正的执行,但是还是会预留预留一些资源空间出来的,我们需要将这些资源空间回滚。

  1. 回滚预留的余额
  2. 回滚库存
  3. 创建订单
    在这里插入图片描述

我们可以看到这个TCC分布式事务其实是让应用自己定义数据库操作的粒度,使得降低锁冲突和锁的粒度,提高吞吐量。

当然我们也可以看到TCC方案的不足之处:

  1. 对应用的侵入性强:业务逻辑的每个分支都需要实现try、confirm、cancel三个操作,应用侵入性较强,改造成本高。
  2. 实现难度较大且复杂:需要按照网络状态、系统故障等不同的失败原因实现不同的回滚策略
  3. 为了满足一致性的要求,Confirm和Cancel接口必须实现幂等

代码实现

在这里插入图片描述

我们用Go语言简单实现一下TCC吧,例子就用我们上面举的。

  • Participant:定义TCC的三个接口,Try、Confirm、Cancel
type Participant interface {Try(ctx context.Context) errorConfirm(ctx context.Context) errorCancel(ctx context.Context) error
}
  • Coordinator:定义TCC事务协调者
type Coordinator struct {participants []Participant
}
func NewCoordinator(participants ...Participant) *Coordinator {return &Coordinator{participants: participants,}
}
  • 执行TCC事务:Try阶段,全部执行,如果有错误,再全部取消(这里我实现比较暴力,感兴趣的同学可以提pr优化)
var tryErr error
for _, p := range c.participants {if err := p.Try(ctx); err != nil {// Try阶段失败,执行CanceltryErr = err}
}
if tryErr != nil {c.cancelAll(ctx)return tryErr
}
  • 如果Try阶段有error,执行CancelAll,执行所有参与者的Cancel操作
func (c *Coordinator) cancelAll(ctx context.Context) {var wg sync.WaitGrouperrChan := make(chan error, len(c.participants))for _, p := range c.participants {wg.Add(1)go func(p Participant) {defer wg.Done()if err := p.Cancel(ctx); err != nil {errChan <- fmt.Errorf("cancel failed: %w", err)}}(p)}wg.Wait() // 等待所有Cancel操作完成close(errChan)// ...
}
  • 如果Try执行正常,则进行Confirm
var confirmErr error
for _, p := range c.participants {if err := p.Confirm(ctx); err != nil {confirmErr = fmt.Errorf("confirm phase failed: %w", err)break}
}

接着我们举个account service的例子来实现TCC的Try、Confirm、Cancel接口:

在这里插入图片描述

  • account 信息服务定义:账户服务
type AccountService struct {accountID    string  // 账号amount       float64 // 总金额frozen       float64 // 预留的金额deductAmount float64 // 添加要扣减的金额字段
}
func NewAccountService(accountID string, balance float64) *AccountService {return &AccountService{accountID: accountID,amount:    balance,}
}
  • Try 函数实现 & 预留资源
func (a *AccountService) PrepareTry(amount float64) {a.deductAmount = amount // 预留出应该需要多少钱
}func (a *AccountService) Try(ctx context.Context) error {a.frozen = a.deductAmount // 冻结预留的金额a.amount -= a.deductAmount // 减去预留的金额if a.amount < 0 { // 如果小于0,也就是账号不足,返回错误return errors.New("insufficient balance")}return nil
}
  • confirm 函数实现:确认操作,实际业务中可能将冻结金额转出,扣除数据库的之类的
func (a *AccountService) Confirm(ctx context.Context) error {a.frozen = 0return nil
}
  • cancel 函数实现:取消操作,回滚预留的金额
func (a *AccountService) Cancel(ctx context.Context) error {a.amount += a.deductAmounta.frozen = 0return nil
}
  • 单测:
func TestPaymentTCCSuccess(t *testing.T) {account := NewAccountService("FanOne", 1000.0)inventory := NewInventoryService("iPhone18", 10)bizData := struct {// 准备业务数据OrderID  stringAmount   float64Quantity int}{OrderID:  "FanOne-Apple-Success",Amount:   500.0,Quantity: 2,}// 设置预留资源account.PrepareTry(bizData.Amount)inventory.PrepareTry(bizData.Quantity)coordinator := NewCoordinator(account, inventory)// 创建TCC协调者err := coordinator.Execute(context.Background())// 执行TCC事务assert.NoError(t, err)// 验证结果assert.Equal(t, 500.0, account.amount)assert.Equal(t, 0.0, account.frozen)assert.Equal(t, 8, inventory.quantity)assert.Equal(t, 0, inventory.frozen)
}

结果符合预期
在这里插入图片描述

http://www.dtcms.com/a/502221.html

相关文章:

  • 流行网站开发工具城建中心官网查询证书
  • 精美网站制作公司网络最好的运营商
  • 深圳制作网站主页网页制作和网页制作技术
  • 网站制作的动画怎么做的企业工商信息查询
  • 中药材天地网做中药零售网站给公司做网站数据分析
  • 关于加强网站建设和管理的通知聊城企业网站建设公司
  • 网站建设的常用技术在深圳怎么注册一家公司
  • 北京网站建设及优化怎样让公司网站更吸引人
  • 用dw如何做网站网站制作公司石家庄
  • 备案信息查询手机网站怎么优化
  • 盘锦做网站专家我要自学网app下载
  • 门户网站 源码个人中心页面
  • 锦州网站建设动态可以浏览的外文网站
  • 网站开发赚不赚钱WordPress文章可视化php代码
  • 怎样才能增加网站重庆公司网站建设价格
  • 旅游公司网站建设pptphp网站有哪些
  • 中山企业建网站网站建设与推广公司
  • 郑州中小企业网站制作石家庄网红打卡地
  • 58和搜房那个网站做房产好wordpress 打赏不能用
  • 东莞九江网站制作中国人事建设部网站
  • 做seo网站诊断书怎么做app封装平台
  • 太原市住房与城乡建设厅网站dw做网站 后台用什么后台
  • 微信投票网站制作海口建站网站模板
  • 南海网站推广个人微信公众平台注册
  • 网站适配手机怎么做电子商务网站建设与管理课后题
  • 量力商务大厦网站建设腾讯云官网登录入口
  • 网投怎么做网站wordpress判断是否开启用户注册
  • 网站建设哪家好就推 鹏博资讯做轮播海报的网站
  • 菜单网站图片素材wordpress中英文标题
  • 网站建设视频vs技术支持 贵阳贵阳网站建设