4.3 分布式事务场景
将一个大的应用系统拆分为多个可以独立部署的应用服务,需要各个服务远程协作才能完成某些事务操作,这就涉及分布式事务的问题。总的来讲,分布式事务会在3种场景下产生,分别是跨JVM进程、跨数据库实例和多服务访问单数据库。
4.3.1 跨JVM进程
将单体项目拆分为分布式、微服务项目之后,各个服务之间通过远程REST或者RPC调用来协同完成业务操作。典型的场景是商城系统的订单微服务和库存微服务,用户在下单时会访问订单微服务。订单微服务在生成订单记录时,会调用库存微服务来扣减库存。各个微服务部署在不同的JVM进程中,此时会产生因跨JVM进程而导致的分布式事务问题。商城系统中跨JVM进程产生分布式事务的场景如图4-6所示。
图4-6 商城系统中跨JVM进程产生分布式事务场景
4.3.2 跨数据库实例
单体系统访问多个数据库实例,也就是跨数据源访问时会产生分布式事务。例如,系统中的订单数据库和交易数据库放在不同的数据库实例中,当用户发起退款时,会同时操作用户的订单数据库和交易数据库(在交易数据库中执行退款操作,在订单数据库中将订单的状态变更为已退款)。由于数据分布在不同的数据库实例中,需要通过不同的数据库连接会话来操作数据库中的数据,因此产生了分布式事务。商城系统中跨数据库实例产生分布式事务场景如图4-7所示。
图4-7 商城系统中跨数据库实例产生分布式事务场景
4.3.3 多服务访问单数据库
多个微服务访问同一个数据库,例如,订单微服务和交易微服务访问同一个数据库就会产生分布式事务,原因是多个微服务访问同一个数据库,本质上也是通过不同的数据库会话来操作数据库,此时就会产生分布式事务。商城系统中多服务访问单数据库产生分布式事务的场景如图4-8所示。
跨数据库实例场景和多服务访问单数据库场景,在本质上都会产生不同的数据库会话来操作数据库中的数据,进而产生分布式事务。这两种场景是比较容易被忽略的。
图4-8 商城系统中多服务访问单数据库产生分布式事务的场景