cim系统中的分布式事务:Seata集成实践

cim系统中的分布式事务:Seata集成实践

【免费下载链接】cim 📲cim(cross IM) 适用于开发者的分布式即时通讯系统 【免费下载链接】cim 项目地址: https://gitcode.com/gh_mirrors/ci/cim

1. 分布式事务痛点与解决方案

在分布式系统中,跨服务的数据一致性一直是开发者面临的难题。当用户在cim系统中发送消息时,需要确保消息成功存储到离线消息模块、路由信息正确更新到路由服务,以及用户状态同步到客户端服务。传统的本地事务无法保证这些跨服务操作的原子性,而Seata作为一款开源的分布式事务解决方案,能够很好地解决这一问题。

2. Seata集成准备工作

2.1 引入Seata依赖

首先,需要在项目的pom.xml文件中添加Seata相关依赖。以cim-common模块为例,在cim-common/pom.xml中添加以下依赖:

<dependency>
    <groupId>io.seata</groupId>
    <artifactId>seata-spring-boot-starter</artifactId>
    <version>1.6.1</version>
</dependency>
<dependency>
    <groupId>io.seata</groupId>
    <artifactId>seata-all</artifactId>
    <version>1.6.1</version>
</dependency>

2.2 配置Seata

在各服务模块的配置文件中添加Seata相关配置。以cim-server模块为例,在cim-server/src/main/resources/application.properties中添加:

# Seata配置
seata.tx-service-group=cim_tx_group
seata.service.vgroup-mapping.cim_tx_group=default
seata.service.grouplist.default=127.0.0.1:8091
seata.config.type=file
seata.registry.type=file

3. Seata在cim系统中的实践

3.1 消息发送场景的分布式事务

在消息发送场景中,涉及到消息存储、路由更新和状态同步三个关键步骤。我们使用Seata的AT模式来保证这三个步骤的原子性。

首先,在消息发送服务中添加@GlobalTransactional注解,开启全局事务:

@Service
public class OfflineMsgServiceImpl implements OfflineMsgService {
    
    @Autowired
    private OfflineMsgDb offlineMsgDb;
    
    @Autowired
    private RouteService routeService;
    
    @Autowired
    private UserStatusService userStatusService;
    
    @GlobalTransactional(rollbackFor = Exception.class)
    public void sendMessage(SendMsgReqVO msg) {
        // 1. 存储离线消息
        offlineMsgDb.save(msg);
        
        // 2. 更新路由信息
        routeService.updateRoute(msg.getSenderId(), msg.getReceiverId());
        
        // 3. 同步用户状态
        userStatusService.updateStatus(msg.getSenderId(), "online");
    }
}

3.2 事务协调流程

Seata的AT模式通过以下步骤保证分布式事务的一致性:

  1. TM(事务管理器):发起全局事务,对应cim系统中的消息发送服务
  2. RM(资源管理器):管理分支事务,对应cim系统中的离线消息模块路由服务和用户状态服务。
  3. TC(事务协调器):协调全局事务的提交或回滚。

Seata事务协调流程

4. 集成效果验证

4.1 正常场景验证

当所有步骤都成功执行时,Seata会提交全局事务,确保消息存储、路由更新和状态同步都生效。

4.2 异常场景验证

当某个步骤失败时,Seata会回滚所有已执行的步骤。例如,当路由更新失败时,已存储的离线消息和已更新的用户状态会被回滚,保证数据一致性。

我们可以通过测试用例来验证异常场景下的事务回滚:

@Test
public void testTransactionRollback() {
    try {
        offlineMsgService.sendMessage(invalidMsg);
        fail("Expected exception not thrown");
    } catch (Exception e) {
        // 验证离线消息未被存储
        Assert.assertEquals(0, offlineMsgDb.count(invalidMsg.getMsgId()));
        
        // 验证路由信息未被更新
        Assert.assertNull(routeService.getRoute(invalidMsg.getSenderId(), invalidMsg.getReceiverId()));
        
        // 验证用户状态未被更新
        Assert.assertEquals("offline", userStatusService.getStatus(invalidMsg.getSenderId()));
    }
}

5. 总结与展望

通过将Seata集成到cim系统中,我们成功解决了分布式环境下跨服务数据一致性的问题。未来,我们将进一步优化Seata的配置,提高事务执行效率,并探索TCC模式在更复杂场景下的应用。

官方文档:doc/QA.md Seata集成源码:cim-forward-route/src/main/java/com/crossoverjie/cim/route/service/impl/OfflineMsgServiceImpl.java 项目教程:README.md

【免费下载链接】cim 📲cim(cross IM) 适用于开发者的分布式即时通讯系统 【免费下载链接】cim 项目地址: https://gitcode.com/gh_mirrors/ci/cim

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值