简体   繁体   English

juCalendar object 在 PreparedStatement#setTimestamp、ResultSet#getTimestamp 中是不可变的/线程安全的吗?

[英]Is j.u.Calendar object immutable/thread-safe in PreparedStatement#setTimestamp, ResultSet#getTimestamp?

I'm performing some micro optimisations and have noticed that application constructs new juCalendar object on every call of ResultSet#getTimestamp or ResultSet#getTimestamp like:我正在执行一些微优化,并注意到应用程序在每次调用ResultSet#getTimestampResultSet#getTimestamp时都会构造新的 juCalendar object,例如:

Timestamp timestamp = rs.getTimestamp(name, Calendar.getInstance(UTC));

I tried to research whether it is possible to use singleton object and have discovered following:我试图研究是否可以使用 singleton object 并发现以下内容:

  • H2 driver does not mutate calendar object and consumes the result of juCalendar#getTimeZone call H2 驱动程序不会改变日历 object 并使用juCalendar#getTimeZone调用的结果
  • PostgreSQL driver behaves similarly to H2 PostgreSQL 驱动程序的行为类似于 H2
  • Oracle driver copies juCalendar via Calendar.getInstance(cal.getTimeZone()) and mutates a copy Oracle 驱动程序通过Calendar.getInstance(cal.getTimeZone())复制juCalendar并变异副本

So, it seems that juCalendar could be a singleton in case of particular JDBC drivers, but is it true for all JDBC drivers, ie are there any specifications/recommendations for driver vendors?因此,在特定的 JDBC 驱动程序的情况下,似乎 juCalendar 可能是 singleton,但对于所有 JDBC 驱动程序来说都是如此吗?

The only thing the JDBC specification says is in the javadoc. JDBC 规范唯一说的是 javadoc。

For PreparedStatement.setTimestamp (and similar for setDate and setTime ):对于PreparedStatement.setTimestamp (与setDatesetTime类似):

Sets the designated parameter to the given java.sql.Timestamp value, using the given Calendar object.使用给定的Calendar object 将指定参数设置为给定的java.sql.Timestamp值。 The driver uses the Calendar object to construct an SQL TIMESTAMP value, which the driver then sends to the database.驱动程序使用Calendar object 构造 SQL TIMESTAMP值,然后驱动程序将其发送到数据库。 With a Calendar object, the driver can calculate the timestamp taking into account a custom timezone.使用Calendar object,驱动程序可以在考虑自定义时区的情况下计算时间戳。 [..] [..]

For ResultSet.getTimestamp (and similar for getDate and getTime ):对于ResultSet.getTimestamp (对于getDategetTime类似):

[..] This method uses the given calendar to construct an appropriate millisecond value for the timestamp if the underlying database does not store timezone information. [..] 如果基础数据库不存储时区信息,此方法使用给定的日历为时间戳构造适当的毫秒值。

Both describe the Calendar parameter as:两者都将Calendar参数描述为:

the java.util.Calendar object to use in constructing the timestamp java.util.Calendar object 用于构建时间戳

In other words, JDBC implementations are allowed to "use" the calendar object in any way they deem fit.换句话说,允许 JDBC 实现以他们认为合适的任何方式“使用”日历 object。 Some JDBC implementations actually use this calendar instance to perform calculations, others just extract the time zone data and do their calculations in another way (including, but not limited to, creating a new Calendar instance).一些 JDBC 实现实际上使用这个日历实例来执行计算,其他的只是提取时区数据并以另一种方式进行计算(包括但不限于创建一个新的Calendar实例)。

In other words, do not assume that it is safe to reuse the Calendar object across multiple threads.换句话说,不要假设跨多个线程重用Calendar object 是安全的。 Using it across multiple invocations in the same thread is probably safe, but even that could be a dangerous assumption (eg you may want to reset the time zone with setTimeZone ).在同一线程中的多个调用中使用它可能是安全的,但即使这样也可能是一个危险的假设(例如,您可能希望使用setTimeZone重置时区)。 However, it would be better to simply not use it at all, and instead switch to using LocalDateTime , which foregoes time zone manipulation, or - assuming the column is actually a TIMESTAMP WITH TIME ZONE , OffsetDateTime .但是,最好根本不使用它,而是改用LocalDateTime ,它放弃了时区操作,或者 - 假设该列实际上是TIMESTAMP WITH TIME ZONEOffsetDateTime

I would also be wary of making optimizations targeting the behaviour of a specific driver.我也会警惕针对特定驱动程序的行为进行优化。 If the implementation of the driver changes, you could suddenly be faced with a hard to diagnose issues like wrong timestamp values caused by race-condition/incorrect shared use of the Calendar .如果驱动程序的实现发生变化,您可能会突然面临难以诊断的问题,例如由竞争条件/不正确的Calendar共享使用引起的错误时间戳值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM