我们已经编写了一个PL/pgSQL函数来将时间戳记录到审计表中。 然而,PostgresSQL语句缓存并没有在每个 调用,这将导致过时(意味着旧的)时间戳记录在审计表中。你知道吗
我们正在运行Postgres9.2。根据文件
http://www.postgresql.org/docs/9.2/static/plpgsql-implementation.html#PLPGSQL-PLAN-CACHING(滚动到文章底部),建议依赖于对now()
的调用。你知道吗
此功能未按预期工作:
CREATE OR REPLACE FUNCTION save(txd integer) RETURNS void AS $$
BEGIN
INSERT INTO audit (id, mtime) VALUES (txd,now());
END;$$
表定义为:
CREATE TABLE audit (
id integer NOT NULL,
mtime timestamp without time zone NOT NULL,
CONSTRAINT audit_pkey PRIMARY KEY (id)
)
可以使用一个使用psycopg2
的简单python 2.7脚本来演示这个问题:
import datetime, psycopg2, time
def tm():
# connect and clear contents
con = psycopg2.connect('dbname=postgres user=postgres')
cur = con.cursor()
cur.execute('TRUNCATE audit')
# Add a record, wait a second, add another
cur.execute('SELECT save(1)')
time.sleep(1.0)
cur.execute('SELECT save(2)')
# List the contents
cur.execute('SELECT * FROM audit')
for row in cur.fetchall():
print("modified %s" % row[1])
cur.close()
con.close()
如果运行这个脚本,您会注意到modified times的两个实例将报告完全相同的值,即使我们在插入之间插入了一个小的1秒睡眠
>>> tm()
modified 2016-05-10 11:05:21.766005
modified 2016-05-10 11:05:21.766005
注意:我们甚至尝试了postgres在linked中提供的例子 文章。使用他们的示例,输出没有差别:
CREATE OR REPLACE FUNCTION save(txd integer) RETURNS void AS $$
DECLARE
curtime timestamp;
BEGIN
curtime = 'now';
INSERT INTO audit (id, mtime) VALUES (txd,curtime);
END;$$
有人能告诉我们哪里出了问题吗?你知道吗
now()
返回事务开始时的时间戳;这将导致事务中的所有时钟读数产生相同的值(这通常是您想要的)。你知道吗如果您想要子事务级别的实际时间,则需要
clock_timestamp()
http://www.postgresql.org/docs/9.5/static/functions-datetime.html相关问题 更多 >
编程相关推荐