当前位置: 首页 > news >正文

网站策划与设计保定关键词优化软件

网站策划与设计,保定关键词优化软件,用护卫神做共享网站,做网站要用什么软件图文教程Spring Boot 配置多数据源并手动配置事务 一、为什么多数据源需要手动配置?二、配置多数据源1. 数据源配置类 (DataSourceConfig)2. 主数据库 MyBatis 配置类 (PrimaryDbMyBatisConfig)3. 从数据库 MyBatis 配置类 (SecondaryDbMyBatisConfig)4. application.yml 配…

Spring Boot 配置多数据源并手动配置事务

  • 一、为什么多数据源需要手动配置?
  • 二、配置多数据源
    • 1. 数据源配置类 (DataSourceConfig)
    • 2. 主数据库 MyBatis 配置类 (PrimaryDbMyBatisConfig)
    • 3. 从数据库 MyBatis 配置类 (SecondaryDbMyBatisConfig)
    • 4. application.yml 配置
    • 5. 使用 @Transactional 指定事务管理器
  • 三、问题说明:will not be managed by Spring
  • 四、总结


在现代企业级应用中,往往会涉及到多个数据库的使用。例如,一个应用可能需要同时操作不同的业务数据库,或分离读写操作。

Spring Boot 提供了对多数据源的支持,但在某些情况下,自动配置可能无法满足复杂的需求。特别是在事务管理方面,当需要在多个数据源间进行操作时,默认的事务管理方式可能不适用,或者无法满足更高的灵活性需求。

因此,手动配置多个数据源并支持事务管理是一个常见的解决方案。

一、为什么多数据源需要手动配置?

  1. 多数据源隔离:

    在微服务架构或者不同模块之间可能会使用不同的数据库,每个数据库有独立的数据源和事务管理。如果使用自动配置的方式,Spring Boot会自动配置一个数据源和一个事务管理器,这可能会导致不同数据源的事务冲突或共享问题。因此,需要手动配置多个数据源和多个事务管理器

  2. 跨数据源的事务管理:

    Spring 默认的事务管理仅适用于单一数据源,如果在一个方法中涉及到多个数据源,Spring并不会自动处理这些数据源之间的事务关系。这时,我们需要显式地配置事务管理器,以便手动控制事务的提交与回滚。

  3. 灵活的事务控制:

    有时我们可能需要在不同的数据源之间手动控制事务,比如先操作主数据源,再操作从数据源,或者在同一个方法中对多个数据源进行操作。这时,手动配置事务管理器可以为我们提供更高的灵活性和控制能力。

二、配置多数据源

1. 数据源配置类 (DataSourceConfig)

这个配置类主要负责配置 primary_db 和 secondary_db 两个数据源,并为它们设置基本的连接属性。

@Configuration
@EnableTransactionManagement
public class DataSourceConfig {/*** 配置主数据库(primary_db)数据源* * 这个方法使用 `@ConfigurationProperties` 注解,从 `application.yml` 配置文件中读取 * `spring.datasource.primary_db` 下的配置,自动配置数据源的连接信息(如 URL、用户名、密码等)。* * @return 配置的主数据库数据源对象*/@Bean(name = "primaryDataSource")@ConfigurationProperties(prefix = "spring.datasource.primary_db")public DataSource primaryDataSource() {return DataSourceBuilder.create().build(); // 创建并返回数据源对象}/*** 配置从数据库(secondary_db)数据源* * 该方法使用 `@ConfigurationProperties` 注解,从 `application.yml` 配置文件中读取 * `spring.datasource.secondary_db` 下的配置,自动配置数据源的连接信息。* * @return 配置的从数据库数据源对象*/@Bean(name = "secondaryDataSource")@ConfigurationProperties(prefix = "spring.datasource.secondary_db")public DataSource secondaryDataSource() {return DataSourceBuilder.create().build(); // 创建并返回数据源对象}}
  • primaryDataSource()secondaryDataSource() 方法用于创建和配置两个数据源。通过 @ConfigurationProperties 注解,Spring 会自动读取配置文件中的数据源信息,并将其与 DataSource 配置绑定。DataSourceBuilder.create().build() 是 Spring Boot 提供的便捷方式来创建数据源实例。

  • @EnableTransactionManagement 启用了事务管理功能,允许你在需要的地方使用 @Transactional 注解来声明事务。

2. 主数据库 MyBatis 配置类 (PrimaryDbMyBatisConfig)

这个配置类负责配置与主数据库(primary_db)相关的 MyBatis 组件。它包含了 MyBatis 的 SqlSessionFactory 和事务管理器配置。

@Configuration
@EnableTransactionManagement
@MapperScan(basePackages = "com.cx.mail.mapper.primary_db", sqlSessionFactoryRef = "primaryDbSqlSessionFactory")
public class PrimaryDbMyBatisConfig {@Autowired@Qualifier("primaryDataSource")private DataSource primaryDataSource;/*** 配置主数据库的 MyBatis SqlSessionFactory* * 创建并配置 MyBatis 的 `SqlSessionFactory`,它是 MyBatis 用来与数据库交互的核心组件。* 在这个配置中,我们指定了使用的 `primaryDataSource` 数据源。* * @return 配置好的 SqlSessionFactory 对象* @throws Exception 可能抛出异常,例如创建 `SqlSessionFactory` 时出错*/@Beanpublic SqlSessionFactory primaryDbSqlSessionFactory() throws Exception {MybatisSqlSessionFactoryBean factory = new MybatisSqlSessionFactoryBean();factory.setDataSource(primaryDataSource); // 设置使用的主数据库数据源// 配置全局设置,主要是 MetaObjectHandler,用于自动填充字段GlobalConfig globalConfig = GlobalConfigUtils.defaults();globalConfig.setMetaObjectHandler(new EntityAutoFillHandler()); // 自动填充创建时间和更新时间factory.setGlobalConfig(globalConfig);// 配置 MyBatis Plus 插件MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 添加分页插件factory.setPlugins(interceptor);// 配置 MyBatis 基本设置MybatisConfiguration configuration = new MybatisConfiguration();configuration.setMapUnderscoreToCamelCase(true); // 将数据库字段下划线命名转换为 Java 类的驼峰命名法configuration.setLogImpl(StdOutImpl.class); // 配置 SQL 打印factory.setConfiguration(configuration);// 配置 MyBatis Mapper XML 文件的位置factory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/primary_db/*.xml"));return factory.getObject(); // 返回创建的 SqlSessionFactory}/*** 配置主数据库的事务管理器* * 该方法创建一个 `DataSourceTransactionManager`,它是 Spring 提供的事务管理器,用来处理主数据库的事务。* * @param dataSource 主数据库的数据源* @return 配置好的事务管理器*/@Primary@Bean(name = "primaryDbTransactionManager")public DataSourceTransactionManager primaryDbTransactionManager(@Qualifier("primaryDataSource") DataSource dataSource) {return new DataSourceTransactionManager(dataSource); // 返回主数据库的事务管理器}
}
  • primaryDbSqlSessionFactory() 方法配置了主数据库的 SqlSessionFactory,并指定了与该数据库交互时的 MyBatis 配置。

  • primaryDbTransactionManager() 方法创建了主数据库的事务管理器(DataSourceTransactionManager),使得我们可以通过 @Transactional 注解来管理与主数据库相关的事务。

3. 从数据库 MyBatis 配置类 (SecondaryDbMyBatisConfig)

这个配置类与主数据库配置类似,但是它专门配置与从数据库(secondary_db)相关的 MyBatis 组件。

@Configuration
@EnableTransactionManagement
@MapperScan(basePackages = "com.cx.mail.mapper.secondary_db", sqlSessionFactoryRef = "secondaryDbSqlSessionFactory")
public class SecondaryDbMyBatisConfig {@Autowired@Qualifier("secondaryDataSource")private DataSource secondaryDataSource;/*** 配置从数据库的 MyBatis SqlSessionFactory* * 创建并配置从数据库的 `SqlSessionFactory`,它将用于从数据库的 MyBatis 操作。* * @return 配置好的 SqlSessionFactory 对象* @throws Exception 可能抛出异常,例如创建 `SqlSessionFactory` 时出错*/@Bean(name = "secondaryDbSqlSessionFactory")public SqlSessionFactory secondaryDbSqlSessionFactory() throws Exception {MybatisSqlSessionFactoryBean factory = new MybatisSqlSessionFactoryBean();factory.setDataSource(secondaryDataSource); // 设置使用的从数据库数据源// 配置全局设置,主要是 MetaObjectHandler,用于自动填充字段GlobalConfig globalConfig = GlobalConfigUtils.defaults();globalConfig.setMetaObjectHandler(new EntityAutoFillHandler());factory.setGlobalConfig(globalConfig);// 配置 MyBatis Plus 插件MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 添加分页插件factory.setPlugins(interceptor);// 配置 MyBatis 基本设置MybatisConfiguration configuration = new MybatisConfiguration();configuration.setMapUnderscoreToCamelCase(true); // 设置驼峰命名法configuration.setLogImpl(StdOutImpl.class); // 配置 SQL 打印factory.setConfiguration(configuration);// 设置 Mapper XML 文件的位置factory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/secondary_db/*.xml"));return factory.getObject(); // 返回创建的 SqlSessionFactory}/*** 配置从数据库的事务管理器* * 该方法创建一个 `DataSourceTransactionManager`,它是 Spring 提供的事务管理器,用来处理从数据库的事务。* * @param dataSource 从数据库的数据源* @return 配置好的事务管理器*/@Bean(name = "secondaryDbTransactionManager")public DataSourceTransactionManager secondaryDbTransactionManager(@Qualifier("secondaryDataSource") DataSource dataSource) {return new DataSourceTransactionManager(dataSource); // 返回从数据库的事务管理器}
}
  • secondaryDbSqlSessionFactory()secondaryDbTransactionManager() 方法与主数据库的配置类类似,但它们专门用于配置和管理从数据库的 MyBatis 和事务。

4. application.yml 配置

# 本地库
spring:# 数据源配置 mysqldatasource:primary_db:url: jdbc:mysql://localhost:3306/primary_dbusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Driversecondary_db:url: jdbc:mysql://localhost:3306/secondary_dbusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Driver
  • 配置了 primary_dbsecondary_db 两个数据源的连接信息(如 URL、用户名、密码等),这些配置将被数据源配置类读取。

5. 使用 @Transactional 指定事务管理器

在多个数据源配置好之后,需要手动管理事务,确保每个数据源的操作在不同的事务上下文中进行。

使用 @Transactional 指定事务管理器,应该加在需要使用该事务管理器进行事务管理的 服务层方法或类 上。通过 @Transactional 注解来指定使用哪个事务管理器。这样,Spring 会使用指定的事务管理器来管理该方法的事务。

@Service
@Transactional(transactionManager = "primaryDbTransactionManager")  // 显式指定事务管理器
public class AdminServiceImpl implements AdminService {@Autowiredprivate FakeDomainMapper fakeDomainMapper;@Autowiredprivate FakeUserService fakeUserService;/*** 新增域名*/@Overridepublic void addFakeDomain(String domain, String domainDescription) {String loginUsername = FakeSecurityUtil.getUsername();if (!fakeUserService.isFakeUserAdmin(loginUsername)) {throw new FakeServiceException("FORBIDDEN");}FakeDomainEntity fakeDomainEntity = new FakeDomainEntity();fakeDomainEntity.setFakeDomain(domain);if (domainDescription != null) {fakeDomainEntity.setFakeDescription(domainDescription);}fakeDomainEntity.setFakeCreated(new Date());fakeDomainEntity.setFakeModified(new Date());// 设置默认的虚拟配额String fakeDefaultSettings = "default_user_quota:2048;";fakeDomainEntity.setFakeSettings(fakeDefaultSettings);fakeDomainMapper.insertFakeDomain(fakeDomainEntity);}
}
  • @Transactional(transactionManager = "primaryDbTransactionManager") 使得 addFakeDomain 方法使用 primaryDbTransactionManager 来管理事务,这样该方法的事务操作会应用到 primaryDataSource 数据源上。

三、问题说明:will not be managed by Spring

在使用 @Transactional 注解时,如果有多个事务管理器(例如多数据源配置),需要特别注意 指定事务管理器

否则,Spring 无法自动决定使用哪个事务管理器来管理当前方法的事务,可能导致事务 无法被 Spring 管理,从而出现错误或者无法保证事务的一致性。

如果没有指定正确的事务管理器,Spring 可能会抛出类似如下的错误:

在这里插入图片描述

这个问题通常出现在以下两种情况下:

  1. 多个数据源
    应用程序配置了多个数据源,每个数据源有自己的事务管理器。Spring 可能不知道应该使用哪个事务管理器来管理当前方法的事务。

  2. 未指定事务管理器
    在有多个事务管理器的环境下,@Transactional 默认使用主数据源的事务管理器。如果你没有显式指定事务管理器,可能会导致事务无法被正确管理,或者使用错误的事务管理器。


四、总结

通过上述配置,系统能够实现同时操作两个不同的数据源,每个数据源有独立的事务管理、MyBatis 配置等,确保了在进行跨库操作时能够稳定运行。每个模块的配置都进行了明确的注释,方便维护和修改。

  • 在有 多个数据源多个事务管理器 的情况下,必须显式指定 transactionManager,否则事务将不会被 Spring 管理,可能导致错误。

  • 使用 @Transactional(transactionManager = "primaryDbTransactionManager") 来明确指定事务管理器。

  • 默认情况下,如果没有显式指定事务管理器,Spring 只会使用主数据源的事务管理器,其他数据源的事务管理器将无法生效。

  • 通过正确的事务管理器配置,可以确保每个方法或服务层类的事务控制是正确的,从而避免由于事务管理不当导致的数据库操作异常或数据不一致问题。

http://www.khdw.cn/news/6489.html

相关文章:

  • 做网站不给钱宁波seo网络推广外包报价
  • 展览展示设计网站百度推广客服电话人工服务
  • 网站动态logo怎么做甘肃网站推广
  • wordpress欢迎页面模板烟台seo外包
  • 第三方微信网站建设国内免费建站平台
  • 分析网络营销方式化工网站关键词优化
  • 广州动态网站开发关闭站长工具seo综合查询
  • 渑池县建设局网站市场调研问卷调查怎么做
  • 住宅房做旅店是什么网站惠州seo外包服务
  • 何炅做的代言网站seo排名优化的网站
  • 网站开发者所有权归属百度小说排行榜2020
  • 网站封面怎么做seo基础教程
  • 平阳网站制作企业网络营销推广方案
  • 建视频网站系统搜索引擎的网站
  • 简速做网站工作室惠州seo排名
  • 在国际网站做外贸需要条件免费推广方法
  • dede自适应网站注意事项seo服务运用什么技术
  • 三合一建站网站互联网平台推广怎么做
  • 网站xml地图网站建设公司seo关键词
  • 江苏网站快速排名优化北京seo代理公司
  • 开网站做销售seo教学
  • www技术支持 重庆网站建设杭州百度推广代理公司哪家好
  • 网站腾讯qq对话框怎么做长沙网站公司品牌
  • 国外浏览器app兰州网站seo优化
  • 企业网站建设毕业论文网络推广优化招聘
  • 都有哪些方法做动态网站的静态化商品标题优化
  • 新乡专业做网站的公司哪家好谷歌香港google搜索引擎入口
  • 邯郸网站制作与建设网站优化招聘
  • 看一个网站是哪里做的西青seo
  • wordpress阅读付费主题北京百度seo公司