同じコミットされていないトランザクションに挿入されたデータを選択できますか?


21

たぶんこれは愚かな初心者の質問ですが、どこにも答えが見つかりません。どこでもTransaction Isolation、同時トランザクション内のデータの可視性を解決する方法について読んでいます。私の懸念は、単一のトランザクション内の動作です。

トランザクションを開始し、いくつかのデータを挿入した場合、すぐにそれらを選択できますか?まだ同じ、まだコミットされていないトランザクション内ですか?はいの場合、この動作は、並行トランザクションの場合の前述のトランザクション分離と同様の方法で変更できますか?

具体的には、PostgreSQL 9.4をターゲットにしています。

回答:


17

はい。
同じトランザクション内で行ったすべてのことは、同じトランザクション内の以降のコマンドから見ることができます。コミットされるまで、他のトランザクションに対してだけではありません。これは、「ダーティリード」が可能な場合を除きRead uncommitted、すべての分離レベルに当てはまります(ただし、それ自体は質問に影響しません)。

すべてのテーブル行の経過時間と可視性の決定に基づいて、MVCCモデル(マルチバージョン同時実行制御)で実装さTransactionIdれています。同じトランザクションで書き込まれたすべての新しい行バージョンは同じになり、xmin「同時に」発生したと見なされます。

同じコマンド内に複数のCTE(共通テーブル式)の場合があります。それらは順番に実行されると考えるかもしれませんが、1つのCTEが他を参照しない限り、そのシーケンスは任意です。そして、クエリの最初から同じスナップショットがすべて表示されます。

例:

高度な例:


3

やってみよう :

CREATE OR REPLACE FUNCTION public.sp_get_user()
 RETURNS json
 LANGUAGE plpgsql
AS $function$BEGIN

INSERT INTO users (name, password) VALUES ('deadeye', 'test');
RETURN row_to_json(row) FROM (SELECT name, password FROM users WHERE name = 'deadeye') row;

END;$function$

では、テストしましょう:

SELECT sp_get_user();
{"name":"deadeye","password":"test"}

できます !アーウィンが言ったように、トランザクションで行われたすべてはトランザクション内で見ることができます。分離は異なるスレッド間のみです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.