PostgreSQLのnow()はトランザクションの開始時刻を返す

PostgreSQL の Date/Time 関数

PostgreSQL の日付/時間計系関数の時刻は

  • 評価した日時
  • トランザクションの開始日時

の2種類がある。

前者の例としては

  • clock_timestamp()

後者の例としては

  • CURRENT_TIMESTAMP # literal
  • now()
  • transaction_timestamp()

などがある。

前者の場合、clock_timestamp() を評価するたびに、評価した日時が返される。
後者の場合、同じトランザクション内であれば、同じ日時が返される。

多くの日付/時間系関数が後者のような仕様になっている理由について、マニュアルでは次のように記載されている。

9.9. Date/Time Functions and Operators

Since these functions return the start time of the current transaction, their values do not change during the transaction. This is considered a feature: the intent is to allow a single transaction to have a consistent notion of the “current” time, so that multiple modifications within the same transaction bear the same time stamp.

http://www.postgresql.org/docs/current/static/functions-datetime.html#FUNCTIONS-DATETIME-CURRENT

Python/psycopg2 での挙動

Python の PostgreSQL バインディングの psycopg2 では SELECT を含めて SQL を実行すると、トランザクションを開始し、commit するまで idle in transaction (waiting for client inside a BEGIN block) モードになるのがデフォルトの挙動。

Transactions control

In Psycopg transactions are handled by the connection class. By default, the first time a command is sent to the database (using one of the cursors created by the connection), a new transaction is created. The following database commands will be executed in the context of the same transaction – not only the commands issued by the first cursor, but the ones issued by all the cursors created by the same connection.
http://initd.org/psycopg/docs/usage.html#transactions-control

idle in transaction モードでは、何回 now() を呼び出しても、同じトランザクション内なので、同じ日時がかえってくる。

トランザクションを開始しないようにするには、コネクションの分離レベルを ISOLATION_LEVEL_AUTOCOMMIT にするか autocommit プロパティを True にする。

conn.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT)
conn.autocommit = True

元の挙動に戻すには、コネクションの分離レベルを ISOLATION_LEVEL_READ_COMMITTED にするか、autocommit プロパティを False にする。

conn.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_READ_COMMITTED)
conn.autocommit = False

分離レベルを調べる

現在のセッションの分離レベルを調べるには、次のようにする

test => select current_setting('transaction_isolation');
 current_setting
-----------------
 read committed

References

Tagged with: , ,
Posted in database

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Archives
  • RT @__apf__: How to write a research paper: a guide for software engineers & practitioners. docs.google.com/presentation/d… /cc @inwyrd 1 week ago
  • RT @HayatoChiba: 昔、自然と対話しながら数学に打ち込んだら何かを悟れるのではと思いたち、専門書1つだけ持ってパワースポットで名高い奈良の山奥に1週間籠ったことがある。しかし泊まった民宿にドカベンが全巻揃っていたため、水島新司と対話しただけで1週間過ぎた。 それ… 3 weeks ago
  • RT @googlecloud: Ever wonder what underwater fiber optic internet cables look like? Look no further than this deep dive w/ @NatAndLo: https… 3 weeks ago
  • @ijin UTC+01:00 な時間帯で生活しています、、、 6 months ago
  • RT @mattcutts: Google's world-class Site Reliability Engineering team wrote a new book: amazon.com/Site-Reliabili… It's about managing produc… 9 months ago
%d bloggers like this: