GeXiangDong

精通Java、SQL、Spring的拼写,擅长Linux、Windows的开关机

0%

PostgreSQL now()函数

now()函数是postgresql 中用来获取当前时间的函数,需要注意postgresql提供了多个获取当时时间的函数,now只是其中一个。

函数 说明
now() 事务的开始时间,等同于 transaction_timestamp()
transaction_timestamp() 事务的开始时间,等同于now(),同一事务内多次调用返回相同个结果
statement_timestamp() 语句的开始执行时间,同一语句内多次调用结果相同
clock_timestamp() 时钟时间,如果一个SQL语句多次调用(例如有子查询)返回结果可能不同

根据上述说明,如果需要用timestamp字段排序,且顺序非常重要,例如余额变化,然后一个事务中可能有多个insert,用now()就会造成混乱。

可以通过sql测试下这几个函数

1
2
3
4
begin;
select now(), pg_sleep(0.1), transaction_timestamp() , pg_sleep(0.1), statement_timestamp(), pg_sleep(0.1), clock_timestamp(), pg_sleep(0.1), statement_timestamp(), clock_timestamp();
select now(), pg_sleep(0.1), transaction_timestamp() , pg_sleep(0.1), statement_timestamp(), pg_sleep(0.1), clock_timestamp(), pg_sleep(0.1), statement_timestamp(), clock_timestamp();
commit;

在PSQL内执行上面的SQL,会得到如下结果,从结果中可以看到,一个事务内,多个sql的多次now() transaction_timestamp()返回的结果是完全相同的;同一事务内多个语句中的statement_timestamp()返回结果不同,而同一语句中的statement_timestamp()返回结果相同;任意一个clock_timestamp()返回结果都可能不同(pg_sleep(0.1)是让postgresql睡眠0.1秒后继续执行)

tempdb =# begin;
BEGIN
tempdb =*# select now(), pg_sleep(0.1), transaction_timestamp(), pg_sleep(0.1), statement_timestamp(),  pg_sleep(0.1), clock_timestamp(), pg_sleep(0.1), statement_timestamp(), clock_timestamp();
              now              | pg_sleep |     transaction_timestamp     | pg_sleep |     statement_timestamp      | pg_sleep |        clock_timestamp        | pg_sleep |     statement_timestamp      |        clock_timestamp        
-------------------------------+----------+-------------------------------+----------+------------------------------+----------+-------------------------------+----------+------------------------------+-------------------------------
 2022-01-09 15:27:28.976989+08 |          | 2022-01-09 15:27:28.976989+08 |          | 2022-01-09 15:27:34.43345+08 |          | 2022-01-09 15:27:34.737544+08 |          | 2022-01-09 15:27:34.43345+08 | 2022-01-09 15:27:34.838665+08
(1 row)

tempdb=*# select now(), pg_sleep(0.1), transaction_timestamp(), pg_sleep(0.1), statement_timestamp(),  pg_sleep(0.1), clock_timestamp(), pg_sleep(0.1), statement_timestamp(), clock_timestamp();
              now              | pg_sleep |     transaction_timestamp     | pg_sleep |      statement_timestamp      | pg_sleep |       clock_timestamp        | pg_sleep |      statement_timestamp      |        clock_timestamp        
-------------------------------+----------+-------------------------------+----------+-------------------------------+----------+------------------------------+----------+-------------------------------+-------------------------------
 2022-01-09 15:27:28.976989+08 |          | 2022-01-09 15:27:28.976989+08 |          | 2022-01-09 15:27:43.321314+08 |          | 2022-01-09 15:27:43.62673+08 |          | 2022-01-09 15:27:43.321314+08 | 2022-01-09 15:27:43.727897+08
(1 row)

tempdb=*# commit;
COMMIT