根据业务要求,不同的国家设置jvm参数,来确定当前时区。

  1. // -Duser.timezone=Asia/Kolkata 印度加尔各答 GMT+05:30
  2. // -Duser.timezone=Asia/Bangkok 泰国曼谷 GMT+07:00
  3. // -Duser.timezone=Asia/Shangha 中国上海 GMT+08:00

由于各个国家上线项目不完全相同,部分功能在不同的项目有不同实现方式。数据同步时,发生了跨时区同步数据的情况。

例如:

在某个国家部署A服务,在当地时间执行同步任务,可以同步到正确的业务数据,其中业务数据类型使用java.util.Date。

另一个国家部署B服务,同样业务数据类型使用java.util.Date,在当地时间执行同步任务,不可以同步到正确的业务数据,只好改写为java.lang.String类型。

调查原因,发现B服务的jdbc的jar包版本太低,不支持自动时区转换,升级版本为6.0.3,可以正确同步数据。

  • JdbcTimestampValueFactory
  1. public Timestamp createFromTimestamp(int year, int month, int day, int hours, int minutes, int seconds, int nanos) {
  2. if (year == 0 && month == 0 && day == 0) {
  3. throw new DataReadException(Messages.getString("ResultSet.InvalidZeroDate"));
  4. } else {
  5. synchronized(this.cal) {
  6. this.cal.set(year, month - 1, day, hours, minutes, seconds);
  7. Timestamp ts = new Timestamp(this.cal.getTimeInMillis());
  8. ts.setNanos(nanos);
  9. return ts;
  10. }
  11. }
  12. }

但同时发现A服务不需要指定jdbc.url中的serverTimezone=Asia/Shanghai。

跟踪代码MysqlaSession.configureTimezone(),在不指定serverTimezone时,跟踪获取数据库服务器的时区的代码,获取的确实为CST,但在将转换为对应时区时,A服务将CST转为了Asia/Shanghai,但B服务仍然为CST=Asia/Kolkata。

  • MysqlaSession
  1. public void configureTimezone() {
  2. String configuredTimeZoneOnServer = this.getServerVariable("time_zone");
  3. if ("SYSTEM".equalsIgnoreCase(configuredTimeZoneOnServer)) {
  4. configuredTimeZoneOnServer = this.getServerVariable("system_time_zone");
  5. }
  6. String canonicalTimezone = (String)this.getPropertySet().getStringReadableProperty("serverTimezone").getValue();
  7. if (configuredTimeZoneOnServer != null && (canonicalTimezone == null || StringUtils.isEmptyOrWhitespaceOnly(canonicalTimezone))) {
  8. try {
  9. canonicalTimezone = TimeUtil.getCanonicalTimezone(configuredTimeZoneOnServer, this.getExceptionInterceptor());
  10. } catch (IllegalArgumentException var4) {
  11. throw (WrongArgumentException)ExceptionFactory.createException(WrongArgumentException.class, var4.getMessage(), this.getExceptionInterceptor());
  12. }
  13. }
  14. if (canonicalTimezone != null && canonicalTimezone.length() > 0) {
  15. this.serverTimezoneTZ = TimeZone.getTimeZone(canonicalTimezone);
  16. if (!canonicalTimezone.equalsIgnoreCase("GMT") && this.serverTimezoneTZ.getID().equals("GMT")) {
  17. throw (WrongArgumentException)ExceptionFactory.createException(WrongArgumentException.class, Messages.getString("Connection.9", new Object[]{canonicalTimezone}), this.getExceptionInterceptor());
  18. }
  19. }
  20. this.defaultTimeZone = this.serverTimezoneTZ;
  21. }

继续跟进转换代码,在com.mysql.cj.jdbc.util.TimeUtil#loadTimeZoneMappings()中,会加载/com/mysql/cj/jdbc/util/TimeZoneMapping.properties文件,在A服务的资源文件中,有个TimeZoneMapping.properties,并且包含CST=Asia/Shanghai。Git代码提交记录备注为CST TimeZone point to Asia/Shanghai

  • TimeUtil
  1. private static void loadTimeZoneMappings(ExceptionInterceptor exceptionInterceptor) {
  2. timeZoneMappings = new Properties();
  3. try {
  4. timeZoneMappings.load(TimeUtil.class.getResourceAsStream("/com/mysql/cj/jdbc/util/TimeZoneMapping.properties"));
  5. } catch (IOException var5) {
  6. throw ExceptionFactory.createException(Messages.getString("TimeUtil.LoadTimeZoneMappingError"), exceptionInterceptor);
  7. }
  8. String[] var1 = TimeZone.getAvailableIDs();
  9. int var2 = var1.length;
  10. for(int var3 = 0; var3 < var2; ++var3) {
  11. String tz = var1[var3];
  12. if (!timeZoneMappings.containsKey(tz)) {
  13. timeZoneMappings.put(tz, tz);
  14. }
  15. }
  16. }
  17. ``
  18. 重要参考链接:
  19. - https://www.cnblogs.com/sogeisetsu/p/12324161.html
  20. - https://blog.csdn.net/weixin_37015554/article/details/105198428
  21. - https://blog.csdn.net/weixin_41917635/article/details/103719481

【工作记录】JDBC连接MySQL,跨时区调查CST转Asia/Shangha的更多相关文章

  1. JDBC连接MySQL数据库及演示样例

    JDBC是Sun公司制定的一个能够用Java语言连接数据库的技术. 一.JDBC基础知识         JDBC(Java Data Base Connectivity,java数据库连接)是一种用 ...

  2. JDBC连接MySQL数据库及示例

      JDBC是Sun公司制定的一个可以用Java语言连接数据库的技术. 一.JDBC基础知识         JDBC(Java Data Base Connectivity,java数据库连接)是一 ...

  3. java jdbc 连接mysql数据库 实现增删改查

    好久没有写博文了,写个简单的东西热热身,分享给大家. jdbc相信大家都不陌生,只要是个搞java的,最初接触j2ee的时候都是要学习这么个东西的,谁叫程序得和数据库打交道呢!而jdbc就是和数据库打 ...

  4. java jdbc 连接mysql 数据库

    JDBC连接MySQL 加载及注册JDBC驱动程序 Class.forName("com.mysql.jdbc.Driver"); Class.forName("com. ...

  5. 分页查询信息(使用jdbc连接mysql数据库实现分页查询任务)

             分页查询信息       使用jdbc连接mysql数据库实现分页查询任务 通过mysql数据库提供的分页机制,实现商品信息的分页查询功能,将查询到的信息显示到jsp页面上. 本项目 ...

  6. 修改sqlarchemy源码使其支持jdbc连接mysql

    注意:本文不会将所有完整源码贴出,只是将具体的思路以及部分源码贴出,需要感兴趣的读者自己实验然后实现吆. 缘起 公司最近的项目需要将之前的部分业务的数据库连接方式改为jdbc,但由于之前的项目都使用s ...

  7. 【转载】在使用JDBC连接MySql时报错:You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support

    在使用JDBC连接MySql时报错:You must configure either the server or JDBC driver (via the serverTimezone config ...

  8. SpringBoot配置JDBC连接MySql数据库的时候遇到了报错:HikariPool-1 - Exception during pool initialization

    使用SpringBoot做JAVA开发时,JDBC连接MySql数据库的时候遇到了报错: ERROR 10392 --- [ main] com.zaxxer.hikari.pool.HikariPo ...

  9. 被缠上了,小王问我怎么在 Spring Boot 中使用 JDBC 连接 MySQL

    上次帮小王入了 Spring Boot 的门后,他觉得我这个人和蔼可亲.平易近人,于是隔天小王又微信我说:"二哥,快教教我,怎么在 Spring Boot 项目中使用 JDBC 连接 MyS ...

  10. JDBC——使用JDBC连接MySQL数据库

    在JDBC--什么是JDBC一文中我们已经介绍了JDBC的基本原理. 这篇文章我们聊聊如何使用JDBC连接MySQL数据库. 一.基本操作 首先我们需要一个数据库和一张表: CREATE DATABA ...

随机推荐

  1. CentOS 9 Basic Developing environment and IDEs installing guide

    I . Install Google Chrome browser Check the installed chrome and related packages with the command & ...

  2. docker 应用篇————tomcat例子[七]

    前言 虽然我干的事情和java不多,但是例子是为了熟悉原理,而不是为了例子而例子的,故而整理一下tomcat的例子. 正文 使用官方示例: 然后运行一下. 没有找到然后进行下载了. 可以看到这里就已经 ...

  3. 初探Mysql架构和InnoDB存储引擎

    前言 mysql相信大家都不陌生了,分享之前我们先思考几个面试题: 1.undo log和redo log了解过吗?它们的作⽤分别是什么? 2.redo log是如何保证事务不丢失的? 3.mysql ...

  4. 力扣696(java)-计数二进制子串(简单)

    题目: 给定一个字符串 s,统计并返回具有相同数量 0 和 1 的非空(连续)子字符串的数量,并且这些子字符串中的所有 0 和所有 1 都是成组连续的. 重复出现(不同位置)的子串也要统计它们出现的次 ...

  5. iLogtail社区版使用入门 - 采集MySQL Binlog

    简介: MySQL Binlog记录了MySQL的变更日志,业界也有一些方案来同步Binlog的数据,如Canal.MaxWell.DTS等.不同的工具可以实现不同的目标,iLogtail也提供了便捷 ...

  6. 兑现 Service Mesh 的新价值:精确控制“爆炸半径”

    ​简介:本文分享了阿里云内部所沉淀的全链路流量打标与路由的能力,做出服务网格技术新体验的同时,很好地兑现了服务网格的新价值. 作者:至简 软件是以持续迭代的方式去不断演进的.某种程度上,我们并不担心软 ...

  7. 春色满园关不住,带你体验阿里云 Knative

    简介: Knative 是基于 Kubernetes 的开源 Serverless 应用编排框架.阿里云 Knative 在社区Knative基础之上,与阿里云产品进行了深度的融合,给你带来最纯粹的容 ...

  8. 揭秘 cache 访问延迟背后的计算机原理

    ​简介:本文介绍如何测试多级 cache 的访存延迟,以及背后蕴含的计算机原理. CPU 的 cache 往往是分多级的金字塔模型,L1 最靠近 CPU,访问延迟最小,但 cache 的容量也最小.本 ...

  9. [Go] go build 减小二进制文件大小的几种方式

    第一种 是去除不需要的调试信息: go build -ldflags "-s -w" main.go 实测 19M 减小为 15M,幅度 2% 第二种 压缩 UPX: the Ul ...

  10. dotnet SemanticKernel 入门 将技能导入框架

    在上一篇博客中和大家简单介绍了 SemanticKernel 里的技能概念,接下来咱准备将 技能 导入到 SemanticKernel 框架里面,进行一个管道式调用 本文属于 SemanticKern ...