最近公司正在升级Spring Boot版本(从1.5升级到2.1),其间踩到一个非常隐晦的MySQL时区陷阱,具体来说,就是数据库读出的历史数据的时间和实际时间差了14个小时,而新写入的数据又都正常。如果你之前也是使用默认的MySQL时区配置,那么大概率会碰到这个问题,深究其背后的原因又涉及到很多技术细节,故整理出来分享给大家。
首先来看一下原因。升级到Boot 2.1之后,MySQL Connect/J版本也随之升级到8.0,会优先使用连接参数(serverTimezone
)中指定的时区,如果没有指定,则再使用数据库配置的时区,参考下面的官宣(对应的源代码是com.mysql.cj.protocol.a.NativeProtocol#configureTimezone()
)。由于我们之前数据库连接参数没有指定时区,并且数据库配置的是默认的CST
时区(美国中部时区,即-6:00),所以读取出来的时间出现偏差。
Connector/J 8.0 always performs time offset adjustments on date-time values, and the adjustments require one of the following to be true:
- The MySQL server is configured with a canonical time zone that is recognizable by Java (for example, Europe/Paris, Etc/GMT-5, UTC, etc.)
- The server’s time zone is overridden by setting the Connector/J connection property
serverTimezone
(for example,serverTimezone=Europe/Paris
).
找到原因之后