关于事务管理器,在之前的文章《分布式事务之mysql两阶段提交》有介绍。简单的来说,就是独立于业务逻辑,专门负责执行数据库事务的服务。事务管理器对于 RPC 之重要,可以说没有事务管理器,就没有分布式 RPC。
为什么事务管理器重要
首先我来梳理一下没有事务管理器的情况下,RPC 服务怎么调用数据库事务。分布式数据库的情况下需要一台事务管理器管理分布式事务中每台数据库事务的状态。
如果只有一台数据库。每个 RPC 都有自己的连接,所以 RPC 之间无法共享事务。这时考虑以下两种情况:
- 每个 RPC 能访问所有表
- rpc-1 开启了一个事务,同时调用 rpc-2,rpc-2 开启了另一个事务。如果1和2的事务访问同一个表的同一行数据,就会造成死锁。这种情况虽然可以避免,但是排查有难度。
- 每个 RPC 只能访问自己的表
- 如果每个 RPC 只能访问自己的表,那但凡 RPC 间的调用,都会变成分布式事务。这样不但代码量会变得很大,而且效率太低。不推荐这样配置。
因此,只有一台数据库的情况下,我推荐每个 RPC 都能访问所有的数据表,通过测试来避免死锁。只有这一种情况可以不用事务管理器,其他情况都需要。
如何实现事务管理器
如果只有一个数据库,可以自己实现一个事务管理器,rpc-1 先从事务管理器获得事务 id,被调 rpc-2 通过事务 id,获得 rpc-1 的数据库连接。这时的事务管理器就是一个数据库连接池。这里要注意单点问题。
对于分布式的情况,可以用 XA 事务,但是效率不高。可以考虑 TCC 事务,参考《分布式事务之TCC补偿型事务》。