面试题---分布式事务、锁

文章介绍了分布式事务的概念和几种常见的解决方案,如2PC、3PC、TCC以及可靠消息最终一致性等,并详细讨论了2PC的优缺点。Seata作为分布式事务框架,对比传统2PC在架构和效率上的改进被提及。此外,提到了Seata的组件(TC、TM、RM)的角色和职责,以及TCC模式的优缺点。还讨论了分布式锁的实现,包括数据库锁、Redis和Zookeeper的解决方案,并指出Redis实现分布式锁可能遇到的问题及其对策。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、什么是分布式事务,分布式事务你知道哪些解决方案?这些方案如何选型

        概念:用于保证分布式系统不同节点之间的数据一致性

        解决:2PC:二阶段提交。它引入一个事务协调者的角色来协调个参与者的提交和回滚。二阶段指定是准备和提交两个阶段。准备时,事务协调者发出指令,令各参与者把指令完成。所有参与者响应后,事务协调者发出提交命令,各参与者进行事务提交(可以是回滚、提交)

                3PC:2PC升级版。三个阶段,准备阶段、预提交阶段、提交阶段。准备阶段,询问各参与者是否能参与事务。预提交阶段,等待各参与者都回应了,执行预提交。提交阶段,各参与者真正提交事务。

                TCC:它是基于补偿性事务的AP系统的一种实现,补偿也就是说先按照预定方案执行,如果失败了就走补偿方案。它可以自己定义数据操作的粒度,但是对应用的侵入性强,可以用在登录送积分,送优惠券等等场景

                可靠消息最终一致性,指的是当事务发起方执行完本地事务后,就发出一条消息通知其他参与方,并且他们一定能接收到消息并处理事务。适合执行周期长,并且实时性要求不高的场景

                最大努力通知,是在不影响主业务的情况下,尽可能的保证数据的一致性,它适用于一些最终一致性敏感度低的业务,比如支付结果通知

2、什么是2pc,基于什么协议,有什么缺点

        2PC,是将整个事务流程分为两个阶段,P指的是准备阶段,C指的是提交阶段。它常见的标准有XA,JTA,Seata

        由DTP模型定义事务管理器TM和资源管理器RM之间通讯的接口规范叫做XA,它规定应用程序AP通过TM提交和回滚事务,TM通过XA接口来通知RM数据库事务的开始,结束,提交,回滚

        2PC能保证分布式事务的原子性,但是也有很多缺陷

        比如,在第一阶段,如果参与者迟迟不回复协调者,就会造成事务的阻塞,性能不好

        比如,在第二阶段,如果事务协调者发出提交事务指令后宕机,一部分参与者收到消息提交了事务,另一部分没有收到消息没有提交事务,这就会导致数据不一致

        再比如,在第二阶段,如果事务协调者发出提交事务指令后宕机,收到指令的参与者也宕机了,我们就不能确定事务的执行结果,究竟有没有提交

3、Seata相比传统2PC有什么区别,以及优点

         Seata是由阿里中间件团队发起的开源项目Fescar更名而来,是一个开源的分布式事务框架,它通过对本地关系数据库的分支事务协调,来驱动完成全局事务

        Seata的主要优点是性能好,不会长时间占用链接资源,对业务零入侵

        与传统的2PC的区别主要两方面:

                1、在架构层次方面,传统的2PC方案的RM本质就是数据库自身,而Seata的RM是以jar
        包形式作为中间件层部署在应用程序上

                2、在两阶段提交上方面,传统2PC方案是在第二阶段完成才释放资源,而Seata是在第
         一阶段就将本地事务提交,提高了效率

4、Seata的TC,TM,RM的含义,以及作用

        TC:事务协调器,它是独立的中间件,需要独立部署运行,它维护全局事务的运行状态,接收TM指令发起全局事务的提交与回滚,负责与RM通信协调各各分支事务的提交或回滚

        TM:事务管理器,TM需要嵌入应用程序中工作,它负责开启一个全局事务,并最终向TC发起全局提交或全局回滚的指令

        RM:控制分支事务,负责分支注册、状态汇报,并接收事务协调器TC的指令,驱动分支事务的提交和回滚

5、TCC概念、优缺点

     TCC是基于补偿型事务的AP系统的一种实现。补偿指的先按照事先预定的方案去执行,如果失败了就走补偿方案

        它的优点是异步执行效率高,它能对分布式事务中的各个资源分别锁定,分别提交与释放

        它的缺点是对应用的侵入性强,改动成本高,实现难度大   

6、Seata的工作原理

        假设有服务A需要调用服务B,且两个服务都需要修改各自的数据库

        ​ A服务的TM向TC申请开启一个全局事务,全局事务创建成功并生成一个全局唯一的XID

        ​ A服务的RM向TC注册分支事务,并将其纳入XID对应全局事务的管辖

        ​ A服务执行分支事务

        ​ 当调用B服务时,B服务的RM向TC注册分支事务,该分支事务执行,并将其纳入XID对应全局事务的管辖

        ​ B服务执行分支事务,执行完毕后,返回A服务

7、分布式锁

        保证某个公共资源只能在同一时间被多进程应用的某个进程的某一个线程访问时使用锁。

8、分布式锁解决方案

       数据库锁:创建一张锁表,当要锁住资源时就增加一条记录,释放时就将记录删除

       基于redis:Redis提供了一个命令setnx 可以来实现分布式锁,该命令只在键 key 不存在

的情况下 将键 key 的值设置为 value ,若键 key 已经存在, 则 SETNX 命令不做任何动作。

       基于Zookeeper:基于它的层次型的目录树的数据结构,并通过对树上的节点进行有效管

理,可以设计出各种各样的分布式集群管理功能。此外, ZooKeeper本身 也是分布式的。

9、Redis如何实现分布式锁,用什么命令

        主要使用setnx命令实现,在线程抢到资源的使用权时,会使用setnx命令进行枷锁,其他线程就不能访问该资源。当此线程使用完时执行del命令删除锁,就释放了资源的使用权

10、Redis实现分布式锁可能会出现什么问题,如何解决

        锁超时:当锁了资源后突然宕机了,就不能释放锁、释放这个资源,造成死锁的情况,此时就可以为setnx的Key设置过期时间。通过expire命令实现。

       原子性:通过setnx和expire还会在极端情况下出现死锁的情况,就是setnx锁后,但是没来得及设置expire过期时间服务宕机。可以通过set方法设置锁和过期时间

       锁误删:del命令可能会删除其他服务的锁。服务A获取到锁后,在执行业务期间,锁自动过期,业务执行完成后执行删锁的命令,就会把别的锁删除。可以通过判断此锁是不是自己上的锁,把锁的值用UUID生成。

11、Redission的看门狗原理

        Redisson中客户端一旦加锁成功,就会启动一个watch dog看门狗,他会每隔10秒检查一下,如果客户端还持有锁key,那么就会不断的延长锁key的生存时间默认30s。

12、

<think>嗯,用户这次想了解Seata分布式事务面试题及解答。从引用内容看,用户可能正在准备分布式系统相关的技术面试,特别是分布式事务方向。之前讨论过ES和MySQL同步问题,现在转向分布式事务,说明用户的知识面在扩展。 用户引用的内容提到几个关键点:分布式事务的性能开销、Seata的存储方式(文件/MySQL)、TC扩容问题。这应该是用户关注的核心。需要系统性地梳理Seata的面试考点,既要覆盖基础概念,也要深入实现细节。 考虑到面试场景,回答需要结构化:先解释核心概念(如AT/TCC模式),再剖析架构设计(TC/RM/TM交互),最后解决性能/扩容等实际问题。特别要注意用户提到的存储机制——这是高频考点,要解释清楚为什么默认用文件存储而生产环境推荐DB存储。 用户似乎对实现细节特别关注,比如TC分库分表方案。这需要结合Seata源码设计来解释,比如全局事务ID的分片策略。同时要给出性能数据支撑,比如单TC节点支撑的TPS量级,这样面试时才有说服力。 另外注意到用户上次的问题涉及数据同步(Canal),这次转向分布式事务,可能在实际工作中遇到了系统整合问题。可以在解答时适当关联——比如分布式事务对ES数据一致性的影响,但当前问题还是聚焦Seata本身。</think>以下是Seata分布式事务的核心面试题及深度解析,涵盖架构设计、实现原理和性能优化等关键方向: --- ### 一、核心概念与架构 #### 1. Seata的三大核心模块及作用 | **模块** | **角色** | **关键职责** | |----------|-------------------|-----------------------------------------------------------------------------| | TC (Transaction Coordinator) | 事务协调器 | 全局事务管理(开启/提交/回滚)、分支事务注册、事务状态存储[^1] | | TM (Transaction Manager) | 事务管理器 | 定义全局事务边界(`@GlobalTransactional`)、发起全局提交/回滚指令 | | RM (Resource Manager) | 资源管理器 | 分支事务注册、本地事务提交/回滚、生成undo_log(AT模式) | **面试考点**: - **TC高可用实现**:通过注册中心(如Nacos)集群部署,客户端重试机制保障可用性 - **RM与TC交互协议**:基于Netty的RPC通信,协议层使用Seata自定义协议(报文头+消息体) --- ### 二、事务模式深度对比 #### 1. AT模式(默认)实现原理 ```mermaid sequenceDiagram participant TM participant TC participant RM1 participant DB1 TM->>TC: 1. 开启全局事务(XID) TC-->>TM: 返回XID TM->>RM1: 2. 执行SQL(携带XID) RM1->>DB1: 3. 执行业务SQL RM1->>DB1: 4. 生成undo_log(前后镜像) RM1->>TC: 5. 分支事务注册 TM->>TC: 6. 全局提交 TC->>RM1: 7. 异步删除undo_log ``` **核心机制**: - **一阶段提交**:业务SQL与undo_log在同一个本地事务中提交 - **二阶段提交**:TC异步通知各RM删除undo_log(无需回滚) - **二阶段回滚**:RM根据undo_log前镜像生成补偿SQL并校验脏写 **面试考点**: - **脏写校验**:回滚时对比当前数据与undo_log后镜像,若不一致则抛出`BranchRollbackFailed_Retriable` - **性能优势**:相比XA模式减少一次数据库资源定时间 #### 2. TCC模式 vs AT模式 | **维度** | **TCC模式** | **AT模式** | |----------------|-----------------------------|------------------------| | 侵入性 | 高(需实现try/confirm/cancel) | 低(基于代理JDBC) | | 性能 | 更高(无全局) | 中等(一阶段有) | | 适用场景 | 金融支付、积分兑换 | 普通电商交易 | | 事务隔离性 | 业务自定义 | 全局读未提交 | --- ### 三、高性能存储与扩容方案 #### 1. TC事务日志存储策略 ```java // Seata Server配置示例(store.mode决定存储引擎) store { mode = "db" // 可选: file, db, redis db { datasource = "druid" url = "jdbc:mysql://127.0.0.1:3306/seata" user = "root" password = "123456" } } ``` **存储方案对比**: - **file模式**:基于本地磁盘(如RocksDB),部署简单但无法水平扩展 - **db模式**:事务日志存MySQL,支持TC集群化部署(**生产推荐**) - **redis模式**:实验性支持,高性能但存在数据丢失风险 #### 2. TC分库分表扩容方案 当MySQL存储遇到性能瓶颈时: 1. **垂直拆分**:按业务域拆分`global_table`(订单事务/库存事务) 2. **水平拆分**: - 对`global_table`的`xid`取模分片(如64库1024表) - 通过ShardingSphere-Proxy实现透明分片 3. **读写分离**:TC读请求路由到从库,写请求走主库 **性能数据**: - 单TC节点(DB存储)可支撑 **5,000+ TPS** - 分库分表后线性扩展至 **50,000+ TPS** --- ### 四、高频面试题精解 #### Q1:AT模式如何保证隔离性? **答**: 1. **全局机制**: - 一阶段:RM在执行业务SQL前,向TC申请**全局**(`SELECT FOR UPDATE`) - 冲突时:后提交的事务等待前一个事务释放(默认30s超时) 2. **默认隔离级别**:全局读未提交(业务需通过**状态字段**实现最终一致性) #### Q2:TCC模式空回滚问题如何解决? **解法**: ```java // 1. Cancel方法中判断Try是否执行 @Transactional public boolean cancel(BusinessActionContext context) { if (!tryLogMapper.exists(context.getXid())) { // 检查Try日志 insertCancelLog(context); // 记录空回滚标记 return true; } // 正常回滚逻辑 } ``` **防御措施**: - Try阶段插入日志表,Cancel时校验是否存在 - 业务系统需实现**幂等控制**(如唯一键防重) #### Q3:如何避免TC单点故障? **高可用方案**: 1. **部署层**: - TC集群部署(3节点以上) - 通过Nacos/Eureka注册中心实现负载均衡 2. **存储层**: - DB模式:MySQL主从集群 + Keepalived VIP - Redis模式:Redis Sentinel集群 3. **客户端容错**: - TM/RM内置重试机制(指数退避策略) - 本地事务表降级方案(极端情况下启用) --- ### 五、生产环境最佳实践 1. **性能调优参数**: ```properties # TC端配置 server.recovery.committing-retry-period=1000 # 二阶段提交重试间隔(ms) server.undo.log-save-days=7 # undo_log保留天数 # Client端配置 client.rm.lock.retryInterval=10 # 全局重试间隔(ms) client.rm.lock.retryTimes=30 # 全局最大重试次数 ``` 2. **监控体系**: - **Metrics**:通过Seata-Server暴露的`/metrics`端点采集事务成功率/耗时 - **告警规则**:当二阶段回滚率 > 1% 或 平均事务延迟 > 500ms 触发告警 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值