站长统计app网站工作压力大怎样缓解焦虑情绪

张小明 2026/3/12 16:14:38
站长统计app网站,工作压力大怎样缓解焦虑情绪,网页游戏公益服,运营商推广5g技术在实际项目中#xff0c;我们常常会遇到这样的场景#xff1a;业务数据在 MySQL日志 / 时序数据在 TDengine报表数据在 PostgreSQL部分历史数据在 Oracle这时#xff0c;你并不希望它们“互相切换”#xff0c;而是#xff1a;不同的业务 → 使用不同的数据库不同的模块 →…在实际项目中我们常常会遇到这样的场景业务数据在 MySQL日志 / 时序数据在 TDengine报表数据在 PostgreSQL部分历史数据在 Oracle这时你并不希望它们“互相切换”而是不同的业务 → 使用不同的数据库不同的模块 → 绑定不同的数据源这种模式我们称之为多数据源并存注意不是读写分离、动态切换、主从切换一、什么是「多数据源并存」核心思想只有一句话我不切换数据源我只是同时拥有多个 DataSource每一个都明确对应自己的 Mapper / SqlSessionFactory / 事务管理器。在代码里表现为Resource(name mysqlDataSource) private DataSource mysqlDataSource; Resource(name tdengineDataSource) private DataSource tdengineDataSource;其核心特点是同时存在多个 DataSource Bean每个 DataSource 有自己的配置每个 DataSource 对应自己的 Mapper / Dao / Service不使用 AbstractRoutingDataSource不需要 ThreadLocal 切换不互相影响各自为政使用起来一模一样二、适合使用多数据源并存的场景多数据源并存非常适合这类情况✅ 不同数据库类型MySQL TDengineMySQL OracleMySQL MongoDB✅ 职责不同一个是业务库一个是日志库一个是时序库一个是分析库✅ 不存在「切换依赖关系」不需要主从切换不需要读写分离不需要租户隔离比如现在要设计一个无人机轨迹的数据库时序数据一天百万如果使用MySQL没几天就炸了。那我们现在就要引入时序数据库。那我们现在已经引入了两个数据库我们要做到MySQL 有自己的一套 MapperTDengine 有自己的一套 Mapper配置互不干扰使用方式极其统一三、配置两个数据源我这里是用Druidspring: # 配置数据源 datasource: # 1. MySQL 数据源存业务元数据 mysql: driver-class-name:com.mysql.cj.jdbc.Driver url:jdbc:mysql://192.168.112.58:3306/uav-safety?useUnicodetruecharacterEncodingutf-8useSSLfalseserverTimezoneAsia/ShanghaiallowMultiQueriestruerewriteBatchedStatementstrue username:root password:root type:com.alibaba.druid.pool.DruidDataSource # 连接池配置 initialSize:10 min-idle:5 max-active:20 max-wait:60000 time-between-eviction-runs-millis:60000 min-evictable-idle-time-millis:300000 validation-query:SELECT1 testWhileIdle:true pool-prepared-statements:true max-pool-prepared-statement-per-connection-size:20 # 配置监控统计拦截的filters filters:stat,wall,slf4j # 2. TDengine 数据源时序库 tdengine: driver-class-name:com.taosdata.jdbc.rs.RestfulDriver url:jdbc:TAOS-RS://192.168.112.58:6041/uav_safety?useSSLfalse username:root password:taosdata type:com.alibaba.druid.pool.DruidDataSource # 连接池配置 initialSize:7 minIdle:5 maxActive:20 maxWait:60000 time-between-eviction-runs-millis:60000 min-evictable-idle-time-millis:300000 validationQuery:SELECT1 testWhileIdle:true pool-prepared-statements:true max-pool-prepared-statement-per-connection-size:50 # 配置监控统计拦截的filters filters:stat四、创建 MySQL 数据源配置Configuration MapperScan( basePackages com.za.uav.mapper.mysql, sqlSessionFactoryRef mysqlSqlSessionFactory ) publicclassMysqlDataSourceConfig{ Bean(name mysqlDataSource) ConfigurationProperties(prefix spring.datasource.mysql) public DataSource mysqlDataSource(){ returnnew com.alibaba.druid.pool.DruidDataSource(); } Bean(name mysqlSqlSessionFactory) public SqlSessionFactory mysqlSqlSessionFactory( Qualifier(mysqlDataSource) DataSource dataSource ) throws Exception { SqlSessionFactoryBean bean new SqlSessionFactoryBean(); bean.setDataSource(dataSource); return bean.getObject(); } Bean(name mysqlTransactionManager) public DataSourceTransactionManager mysqlTransactionManager( Qualifier(mysqlDataSource) DataSource dataSource ) { returnnew DataSourceTransactionManager(dataSource); } }注意点MapperScan扫描的是com.za.uav.mapper.mysql所有属于 MySQL 的 mapper 都必须放进这个包ConfigurationProperties配置好之后它会自己读取Druid的配置五、 TDengine 数据源配置类Configuration MapperScan( basePackages com.za.uav.mapper.tdengine, sqlSessionFactoryRef tdengineSqlSessionFactory ) publicclassTdengineDataSourceConfig{ Bean(name tdengineDataSource) ConfigurationProperties(prefix spring.datasource.tdengine) public DataSource tdengineDataSource(){ returnnew com.alibaba.druid.pool.DruidDataSource(); } Bean(name tdengineSqlSessionFactory) public SqlSessionFactory tdengineSqlSessionFactory( Qualifier(tdengineDataSource) DataSource dataSource ) throws Exception { SqlSessionFactoryBean bean new SqlSessionFactoryBean(); bean.setDataSource(dataSource); return bean.getObject(); } }重点包名区分Bean 名称区分到这里多数据源就已经正确并存了。六、事务管理器有个重点这里我们不需要TdEngine的事务管理器所以就不创建bean了。但是这个问题很严重所以专门拉一个出来写一下。我们一般单数据源的时候事务管理器只会有一个。所以我们事务用这个Transactional就贼方便。但如果你的系统中有多个事务管理器在使用的时候必须显式指定事务管理器比如MySQL的Transactional(transactionManager mysqlTransactionManager, rollbackFor Exception.class) publicvoidsaveMysql() { mysqlMapper.insert(data); }TDengine的Transactional(transactionManager tdengineTransactionManager, rollbackFor Exception.class) publicvoidsaveTd() { tdMapper.insert(data); }这个一定要有个肌肉记忆。事务可开不得玩笑。如果你是项目负责人可以立一条项目规则只要是 Service 里写Transactional不写transactionManager xxx一律算 BUG。便捷方式因为很麻烦所以其实可以自定义注解比如我们现在可以分成MysqlTx publicvoidsaveUser(){...} TdTx publicvoidsaveRecord(){...}那我们要做的就是——包一层自己的注解进去Target({ElementType.METHOD, ElementType.TYPE}) Retention(RetentionPolicy.RUNTIME) Transactional( transactionManager mysqlTransactionManager, rollbackFor Exception.class ) Documented public interfaceMysqlTx{ }也就是说✅ 我们只是给Transactional起了一个「有语义的别名」TDengine同理。就很方便了。如果一个方法要操作两个数据库怎么办publicvoidsaveAll(){ mysqlMapper.insert(...); tdMapper.insert(...); }我们业务经常要操作两个库那这时候就有问题了。因为Transactional一次只能绑定一个事务管理器所以如果异常了只会保证MySQL 可回滚TDengine 不在这个事务里不回滚。反过来也是一样。那一般这种情况我们常用的就是业务补偿了Transactional(transactionManager mysqlTransactionManager) publicvoidprocess(){ mysqlMapper.insert(order); try { tdMapper.insert(log); } catch (Exception e) { // 自行补偿删 MySQL 或记录异常单 mysqlMapper.deleteById(order.getId()); throw e; } }七、MapperScan这个跟事务差不多重要。Mapper注解就不要用了注册Bean的方式 换成MapperScan不然有时候它会不知道是哪个数据源的会出错。Mapper和xml都要要这样隔离开来放八、和「动态数据源」的核心区别对比九、使用姿势Service publicclassUserService{ Resource private UserMapper userMapper; Resource private TdLogMapper tdLogMapper; MysqlTx publicvoidsaveUser(User user){ userMapper.insert(user); } TdTx publicvoidsaveLog(Log log){ tdLogMapper.insert(log); } }你会发现业务代码根本无感知数据源差异 这就是并存方式最爽的地方。一些常见问题1druidSQL监控不生效我个人反正习惯用Druid的面板。其中有个SQL统计我们发现TD的不会被统计进来。这时候要看看配置一下但记得像 wall 啥的就别配了会空指针。这是因为wall 是为 SQL 注入检测设计的但数据库语法只适配 MySQL 等关系型数据库不兼容 TDengine 的 SQL 方言。2Invalid bound statement (not found):检查一下这个。记得要被扫描到。看看class文件里面没有的话就mvn clean一下再build一遍。然后就是 检查 Mapper 接口方法名和 XML id 是否一致。然后还有一种是MyBatisPlus的记得要用MybatisSqlSessionFactoryBean。Bean(name mysqlSqlSessionFactory) public SqlSessionFactory mysqlSqlSessionFactory(Qualifier(mysqlDataSource) DataSource dataSource) throws Exception { MybatisSqlSessionFactoryBean bean new MybatisSqlSessionFactoryBean(); bean.setDataSource(dataSource); bean.setMapperLocations(new PathMatchingResourcePatternResolver() .getResources(classpath:mapper/mysql/*.xml)); return bean.getObject(); }总结一下很多人一开始接触多数据源脑子里只有一个问题怎么切换于是第一反应就是动态数据源、AbstractRoutingDataSource、ThreadLocal、AOP……但在真实项目里你更应该先问的其实是到底需不需要切换还是各司其职就够了所以这两种方案解决的核心问题是完全不同的动态数据源解决的是「怎么切换」本质对外只有一个 DataSource内部通过 ThreadLocal 路由规则自动切换常见场景读写分离、多租户、分库分表核心难点上下文传递准确性、事务一致性、调试困难多数据源并存解决的是「怎么各司其职」本质多个 DataSource 同时存在每个数据源拥有自己独立的Mapper 扫描SqlSessionFactoryTransactionManager通过 Bean 名称区分不做切换只做分工不同场景下都有每个解决方案的优劣在真实系统中提高系统稳定性的往往不是复杂技巧而是清晰边界。主要是要知道各个方案的注意点在项目中才不会给自己埋雷。
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

网站建设具体工作wordpress将用户锁在前台

鸿蒙Electron边缘AIIIoT进阶实战:智慧工厂全场景协同与数字孪生融合方案 随着工业4.0深化,单一产线协同已无法满足智慧工厂“全流程数字化、全要素智能化、全区域协同化”的核心需求。本文在上一篇“产线级协同”基础上,新增数字孪生虚实联动…

张小明 2026/3/6 15:25:35 网站建设

个人门户网站模板下载中国十大建筑设计院

第一章:PHP 8.6 兼容性测试概述随着 PHP 语言的持续演进,PHP 8.6 即将引入一系列新特性和底层改进。为确保现有项目在升级后仍能稳定运行,兼容性测试成为迁移过程中不可或缺的一环。该测试旨在识别当前代码库中可能受新版本影响的部分&#x…

张小明 2026/3/6 15:25:21 网站建设

网站建设是啥那个网站详情页做的好

你是否曾经在调试Ryzen系统时,面对复杂的电源管理参数感到无从下手?或者为找不到一款能够同时监控SMU状态和调整关键参数的专业工具而烦恼?SMUDebugTool正是为解决这些痛点而生的专业调试工具,它能帮助你深入理解AMD平台的硬件运行…

张小明 2026/3/6 15:25:17 网站建设

网站的登录界面怎么做做网站功能

文章目录系统截图项目技术简介可行性分析主要运用技术介绍核心代码参考示例结论源码lw获取/同行可拿货,招校园代理 :文章底部获取博主联系方式!系统截图 python-uniapp微信小程序的校园求职交友APP的设计与实现_ze1w640g 项目技术简介 Python版本&a…

张小明 2026/3/6 15:25:13 网站建设

罗湖做网站哪家好wordpress浏览器标签

B站视频转文字神器:零基础5分钟快速上手完整指南 【免费下载链接】bili2text Bilibili视频转文字,一步到位,输入链接即可使用 项目地址: https://gitcode.com/gh_mirrors/bi/bili2text 还在为整理B站视频内容而烦恼吗?Bili…

张小明 2026/3/8 2:12:11 网站建设