文章目录
前言
在开发过程中碰到了这样一个问题:同一条sql在本地和线上执行情况不一致,在时间字段上出现不同。
- sql:
其中release_date的类型为timestamptzSELECT ID AS id, version_number AS versionNumber, release_date AS releaseDate FROM library_version WHERE is_valid = 't' <if test="libraryId != null"> and library_id = #{libraryId} </if> ORDER BY (SELECT (regexp_matches(version_number, '^(\d+)'))[1]::int) DESC NULLS LAST limit #{pageSize} offset #{offset}
- idea执行结果:
- 数据库、服务器中执行结果:
可以观察到releaseDate结果有所不同,idea将数据库中的时区默认转化为了东八区时间。而服务器上和数据库中均为UTC时区。
为什么会出现时区不一致的情况?
- idea:连接数据库时设置了东八区,或者本地系统是东八区
- 服务器:运行在UTC时区环境下
- 数据库:可能存储的是UTC时间,不同客户端解释方式不同
也就是说三者时区不一致,导致线上和本地环境执行情况不同。
如何解决?
为了确保时区一致,我们可以检查以下配置是否完备:
- application配置:
# 记得替换ip、port、数据库为自己的 spring.datasource.base.jdbc-url=jdbc:postgresql://xxx.xxx.xxx.xxx:5432/database?timezone=Asia/Shanghai # 在每个sql执行前增加语句,用于设置时区 spring.datasource.hikari.connection-init-sql=SET TIME ZONE 'Asia/Shanghai'
- dockerfile
确保部署的项目时区是东八区ENV TZ=Asia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
- 服务器环境
# 检查服务器时区 date timedatectl status # 设置服务器时区(Linux) sudo timedatectl set-timezone Asia/Shanghai
总结
- 检查代码中,数据库连接中是否设置好时区
- 检查dockerfile中是否设置了时区
- 检查服务器时区
以上为个人学习分享,如有问题,欢迎指出:)