分布式事务与分布式锁

本文探讨了分布式事务在IT技术中的应用,介绍了Seata、TCC、SAGA和XA模式,以及如何通过如Redis和ZooKeeper实现分布式锁。重点讲解了Seata的非侵入式特性及两阶段提交过程中的事务管理机制。
摘要由CSDN通过智能技术生成

 分布式事务          

   我要是一条狗 这块硬骨头 理都不想理,但是谁让我是一名程序员

本地消息表:说白了就是一个记录

   操作信息 存到库中 成功状态改为成功,失败定时任务重试调用

消息队列:rocketMQ 

 半事务的典范,mq中的战斗机!

  1.生产者订单系统发送一条half消息到broker

  2.创建订单,成功与否 向broker发送commit和rollback

  3.向broker提供回调接口,当broker一段时间内half消息没有收到操作命令,则主动调此接口来查询订单是否创建成功

  4.half消息commit了,另一个系统来消费,消费成功 消息销毁 分布式事务成功,上一篇有图可see

  5.失败则重试策略 再失败 死信队列 等待进一步处理

seata:二阶段提交

他来了她来了 高度警惕 over over

微服务框架/at模式/tcc模式/saga模式/xa模式/高可用 Apache Seata

 xa 强一致:acid 两阶段

无侵入,seata拦截并解析用户sql,保存其变更前后的数据镜像undo_log,自动生成事务提交/回滚

rm 本地事务隔离行保证全局隔离,串行化隔离级别下性能问题

tm申请全局锁 tc 生成xid,tm通过微服务调用链传给其他服务

rm本地事务xid分支事务注册到tc ,tc返回说准备吧 rm执行本地事务并告知tc结果

tm请求tc对xid提交或回滚

tc指挥xid所有分支提交 回滚

阿里开源的分布式事务框架 Seata

回滚:回滚日志

   分支事务对应数据库一个回滚日志undo_log,收到回滚据undo生成回滚操作

   收到提交,undo_log响应记录删除掉

rm和tc

监控拦截jdbc,监控到开启了本地事务 自动向tc注册 生成回滚日志 汇报执行结果

二阶段回滚失败

tc命令rm回滚,一个微服务挂掉了,all微服务不执行回滚,直到正常启动,tc重新执行全局回滚

AT 锁缩短 两阶段

加锁 快照

基于xa,两阶段提交,锁时间缩短;隔离级别:读未提交

     拦截解析sql,生成before image 执行sql 保存成after image,生成行锁,image组成undolog,数据更新 undolog放到同一个事务提交 释放本地锁定的资源

脏读

全局,tc记录 可访问其他字段 lock_table 

TCC 三阶段提交

人工编码try confirm cancel接口,实现数据恢复

try资源的检测和预留,修改某个资源 先进行预留

confirm 业务执行和提交,完成操作业务,try成功confirm一定能成功

cancel预留资源释放,try的反向操作

空回滚和业务悬挂:就是try阻塞了先执行的cancel然后再try 

   加一个表记录try和cancel情况,未try不canel

微服务18_分布式事务02:Seatda:四种模式XA、AT、TCC、SAGA_分布式事务 at、tcc、saga 和 xa-CSDN博客

Saga

第二阶段 提交rm不需要处理,回滚执行业务补偿回滚方法

分布式事务Seata原理 - 知乎

百度安全验证

两阶段三阶段

  基本完成sql语句操作未提交,都成功 通知all提交事务/回滚事务

  canCommit是否正常,preCommit操作sql,doCommit提交/回滚事务

      rm加超时机制解决阻塞

分布式锁

所有进程都能访问到的地方设置锁资源,竞争锁资源

   互斥/同一(持锁的删除)/可重入(续租)/容错(自动释放)

redis:单线程处理网络问题

setNx key  value + expire key  locktime 设置key有效时长

getset key value先get再set返回value,没有返回空再将key设置为value

lua脚本

redlock:多节点申请锁,一半以上节点获取成功算获取成功

   

    redission用响应实现(aqs 看门狗 可重入 可续期)

redission分布式锁原理

获取锁:尝试获取两次,否则带过期时间阻塞等,无过期时间死等 (他个糟老锁子)

     无锁超时时间且获取成功,看门狗定时任务scheduleExpirationRenewal自动续期:expiration_renewal_map中遍历判断是否存在

    带过期时间的lock,不会启动看门狗任务

加锁
<T> RFuture<T> tryLockInnerAsync(long waitTime, long leaseTime, TimeUnit unit, long threadId, RedisStrictCommand<T> command) {
    /**
     * key不存在第一次加锁,key的field存中可重入hincrby锁 续期pexpire
     */
    return evalWriteAsync(getRawName(), LongCodec.INSTANCE, command,
            "if ((redis.call('exists', KEYS[1]) == 0) " + // 1
                        "or (redis.call('hexists', KEYS[1], ARGV[2]) == 1)) then " + // 2
                    "redis.call('hincrby', KEYS[1], ARGV[2], 1); " + // 3
                    "redis.call('pexpire', KEYS[1], ARGV[1]); " + // 4
                    "return nil; " +
                "end; " +
                "return redis.call('pttl', KEYS[1]);", // 5
            Collections.singletonList(getRawName()), unit.toMillis(leaseTime), getLockName(threadId));
}
可重入锁

   加锁成功启动看门狗续期pexpire

锁释放 

   1.删除锁

   2.广播释放锁的信息(redis.call('publish', KEYS[2], ARGV[1]))通知阻塞等待的进程(开始加锁时)

   3.取消watchDog,redissonLock.expiration_renewal_map中的id删除,取消netty定时任务

zk

临时节点 有序  watch  cp

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值