作者:瀚高PG实验室 (Highgo PG Lab)- 波罗
now()和clock_timestamp()在事务内两个时间戳函数的不同表现,具体如下:
testdb=# begin;
BEGIN
testdb=# select now();
now
-------------------------------
2018-05-03 14:31:27.343792+08
(1 row)
testdb=# select now();
now
-------------------------------
2018-05-03 14:31:27.343792+08
(1 row)
testdb=# select clock_timestamp();
clock_timestamp
-------------------------------
2018-05-03 14:31:36.263558+08
(1 row)
testdb=# select clock_timestamp();
clock_timestamp
-------------------------------
2018-05-03 14:31:38.279703+08
(1 row)
testdb=# commit;
COMMIT
testdb=# select now();
now
-------------------------------
2018-05-03 14:31:49.329644+08
(1 row)
testdb=# select now();
now
-------------------------------
2018-05-03 14:31:50.427472+08
(1 row)
通过以上演示可以看到在开启一个事务后,通过两次now()函数获取的时间是一样的,直到事务被提交后;另一个时间函数clock_timestamp()却不会有这个问题。
查阅手册关于两个时间函数的描述如下:
其它相关描述信息:
PostgreSQL提供了许多返回当前日期和时间的函数。
这些 SQL 标准的函数全部都按照当前事务的开始时刻返回值,事务内多次调用函数获取时间不变化:
CURRENT_DATE
CURRENT_TIME
CURRENT_TIMESTAMP
CURRENT_TIME(precision)
CURRENT_TIMESTAMP(precision)
LOCALTIME
LOCALTIMESTAMP
LOCALTIME(precision)
LOCALTIMESTAMP(precision)
CURRENT_TIME和CURRENT_TIMESTAMP传递带有时区的值;
LOCALTIME和LOCALTIMESTAMP传递的值不带时区。
CURRENT_TIME、CURRENT_TIMESTAMP、LOCALTIME和 LOCALTIMESTAMP可以有选择地接受一个精度参数, 该精度导致结果的秒域被园整为指定小数位。
如果没有精度参数,结果将被给予所能得到的全部精度。
因为这些函数全部都按照当前事务的开始时刻返回结果,所以它们的值在事务运行的整个期间内都不改变。
我们认为这是一个特性:目的是为了允许一按照当前事务的开始时刻返回个事务在"当前"时间上有一致的概念, 这样在同一个事务里的多个修改可以保持同样的时间戳。
PostgreSQL同样也提供了返回当前语句开始时间的函数, 它们会返回函数被调用时的真实当前时间。这些非 SQL 标准的函数列表如下:
transaction_timestamp()
statement_timestamp()
clock_timestamp()
timeofday()
now()
transaction_timestamp()等价于CURRENT_TIMESTAMP,但是其命名清楚地反映了它的返回值。
statement_timestamp()返回当前语句的开始时刻(更准确的说是收到 客户端最后一条命令的时间)。
statement_timestamp()和transaction_timestamp()在一个事务的第一条命令期间返回值相同,但是在随后的命令中却不一定相同。
clock_timestamp()返回真正的当前时间,因此它的值甚至在同一条 SQL 命令中都会变化。timeofday()是一个有历史原因的PostgreSQL函数。
和clock_timestamp()相似,timeofday()也返回真实的当前时间,但是它的结果是一个格式化的text串,而不是timestamp with time zone值。
now()是PostgreSQL的一个传统,等效于transaction_timestamp()。