当前位置:  首页>> 技术小册>> Java面试指南

分布式事务介绍

Java分布式事务是指跨越多个独立的系统或进程的事务,它们共同参与一个全局的事务。在分布式系统中,每个系统都可能有自己的数据库和事务管理器,因此需要一种机制来确保所有系统在执行分布式事务时保持一致性。

Java分布式事务可以使用两种基本的模式:基于两阶段提交(Two-Phase Commit,2PC)协议和基于补偿事务(Compensating Transaction)机制。2PC是最常用的分布式事务协议,它通过协调器协调参与者的操作来实现全局事务的提交或回滚。

下面是一个基于2PC协议的Java分布式事务示例代码:

添加依赖

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-jta-atomikos</artifactId>
  4. <version>2.6.2</version>
  5. </dependency>

配置数据源和事务管理器

  1. @Configuration
  2. public class DataSourceConfig {
  3. @Bean(name = "dataSource1")
  4. @ConfigurationProperties(prefix = "spring.datasource.ds1")
  5. public DataSource dataSource1() {
  6. return new AtomikosDataSourceBean();
  7. }
  8. @Bean(name = "dataSource2")
  9. @ConfigurationProperties(prefix = "spring.datasource.ds2")
  10. public DataSource dataSource2() {
  11. return new AtomikosDataSourceBean();
  12. }
  13. @Bean(name = "userTransaction")
  14. public UserTransaction userTransaction() throws Throwable {
  15. UserTransactionImp userTransactionImp = new UserTransactionImp();
  16. userTransactionImp.setTransactionTimeout(10000);
  17. return userTransactionImp;
  18. }
  19. @Bean(name = "atomikosTransactionManager", initMethod = "init", destroyMethod = "close")
  20. public TransactionManager atomikosTransactionManager() throws Throwable {
  21. UserTransactionManager userTransactionManager = new UserTransactionManager();
  22. userTransactionManager.setForceShutdown(false);
  23. return userTransactionManager;
  24. }
  25. @Bean(name = "transactionManager")
  26. public PlatformTransactionManager transactionManager() throws Throwable {
  27. return new JtaTransactionManager(userTransaction(), atomikosTransactionManager());
  28. }
  29. }

在这个配置类中,我们使用了Atomikos实现了分布式事务管理器。我们配置了两个数据源dataSource1和dataSource2,它们使用不同的数据库。我们还配置了userTransaction和atomikosTransactionManager两个Bean,用于管理分布式事务。

编写业务逻辑代码

  1. @Service
  2. public class UserServiceImpl implements UserService {
  3. @Autowired
  4. private UserRepository userRepository;
  5. @Override
  6. @Transactional(rollbackFor = Exception.class)
  7. public void transfer(String fromUser, String toUser, int amount) throws Exception {
  8. User user1 = userRepository.findByUsername(fromUser);
  9. User user2 = userRepository.findByUsername(toUser);
  10. if (user1.getBalance() < amount) {
  11. throw new RuntimeException("Insufficient balance.");
  12. }
  13. user1.setBalance(user1.getBalance() - amount);
  14. user2.setBalance(user2.getBalance() + amount);
  15. userRepository.save(user1);
  16. userRepository.save(user2);
  17. }
  18. }

该分类下的相关小册推荐: