从查询中获取较旧的时间戳

Posted

技术标签:

【中文标题】从查询中获取较旧的时间戳【英文标题】:Getting Older timestamp from query 【发布时间】:2018-06-18 06:11:14 【问题描述】:

以下是我使用选择查询获取当前数据库时间的方法。

public Date getDBDateTime()  
    Session session = sessionFactory.getCurrentSession();   
    return (Date) session.createSQLQuery("select now() as date").uniqueResult();    

此方法从数据库返回当前时间戳,但有时此方法会从数据库返回较旧的时间戳。 (有时 30 到 1 分钟)

这是我在spring中调用dao方法的服务层方法。

@Transactional
public void doSomething()
   Date now  = dao.getDBDateTime();
   //service specific logic

需要为某些事件计时计算选择数据库时间,并将数据库和应用服务器从同一时区解耦。

谁能指出我哪里出了问题并提出解决建议?

感谢期待!

【问题讨论】:

你的数据库和应用程序在不同的服务器/时区吗? @AlpeshJikadra 目前他们在不同的服务器上,但时区相同。 很难重现您的问题,我建议以字符串格式获取日期并使用 Java 将该字符串转换为 LocalDateTime getDBDateTime() 是否返回java.util.Date?还是其他Date @RoshanaPitigala 不,它不是 java.util.Date 但它返回 java.sql.Timestamp 【参考方案1】:

now() 不返回挂墙时间,而是返回交易开始时的当前时间戳。在一个事务中重复调用now() 将始终返回相同的值。请参阅the documentation 了解更多信息。

所以我怀疑如果now() 返回一个旧时间,您有一个长时间运行的未处理事务。这是一个应用程序错误,因为长时间运行的事务将使VACUUM 无法正常工作,并且还会长时间锁定对象。

要获取当前的挂钟时间,请使用函数clock_timestamp()

【讨论】:

感谢您的回答,但在我的应用程序中,服务层代码由一个控制器调用,该控制器是一个休息 api,并以毫秒为单位返回。那么怎么会有一个长期运行的事务呢?我的意思是,如果我在下午 2 点触发 api 并且需要 1 秒来返回响应,那么 30s-1m 的旧时间戳也不符合这种逻辑。我错过了什么吗? 我不知道您的设置,但您可以使用SELECT xact_start FROM pg_stat_activity WHERE pid = pg_backend_pid(); 了解您当前交易的开始时间。 感谢使用 clock_timestamp() 实际上解决了这个问题,但我仍然无法弄清楚长时间运行事务背后的原因。我曾经从 sessionfactory 收到的 session 中思考,每次为每个 rest 调用提供一个新事务。你能建议我一些进一步的参考/阅读来解决这个问题吗? 我对Hibernate一无所知,但我认为它要么是那里的错误,要么是你使用它的方式。对不起,如果我不能进一步帮助你。在 PostgreSQL 中设置 log_statement = 'all' 并检查 Hibernate 的真正作用可能很有用。也许这会给你一个线索。

以上是关于从查询中获取较旧的时间戳的主要内容,如果未能解决你的问题,请参考以下文章

pyspark 数据框删除具有较旧时间戳的重复值

使用datastax python-driver从cassandra获取正确的时间戳

SQL查询以获取时间戳列中没有小时的数据

如何从 DB2 中的两个时间戳中获取差异?

防止在基于记录日期的查询中加入较旧的日期记录

通过 linq 对实体查询进行分组,以通过加入表来获取具有最新时间戳的一条记录