1

postgresql への接続には libpqxx を使用しています。そして、1行の1つのテーブルでserialazableクエリを実行するまで、すべて問題ありませんでした。

テーブル:

CREATE TABLE t1(id integer primary key);

ポストグル 9.4.4_x64

pqxx::connection c1(conn_str);
pqxx::connection c2(conn_str);

pqxx::transaction<pqxx::isolation_level::serializable> t1(c1);
t1.exec("INSERT INTO t1 (id) VALUES (25)");

pqxx::transaction<pqxx::isolation_level::serializable> t2(c2);
t2.exec("INSERT INTO t1 (id) VALUES (25)"); //hang here

t2.commit();
t1.commit();

私のプログラムは永久にハングします。PQexec 関数でハングします。なんで?トランザクションの1つをロールバックする必要があると思いますか? でもいいえ?ハングアップするだけです。

更新:純粋な libpq の場合と同じ結果:

c1 = PQconnectdb(conninfo);
c2 = PQconnectdb(conninfo);

res1 = PQexec(c1, "BEGIN");
PQclear(res1);


res1 = PQexec(c1, "INSERT INTO t1 (id) VALUES (104)");
PQclear(res1);

res2 = PQexec(c2, "BEGIN");
PQclear(res2);

res2 = PQexec(c2, "INSERT INTO t1 (id) VALUES (104)");
PQclear(res2);

res2 = PQexec(c2, "END");
PQclear(res2);

res1 = PQexec(c1, "END");
PQclear(res1);

postgresql 9.1 - 同じハング

4

3 に答える 3

0

postgres チームを形成します。

「並行プログラミングでは、デッドロックとは、2 つ以上の競合するアクションがそれぞれ他のアクションが完了するのを待っている状況であり、したがってどちらも完了することはありません。」 https://en.wikipedia.org/wiki/デッドロック

定義それはそもそもデッドロックではありません。「c1」は「c2」が終了するのを待たず、id=104 で問題なく処理を進めることができます。ただし、アプリケーションは、「c2」が挿入を実行するのを頑固に待っているため、c1 に次のコマンドを与えることはありません。これは、「c1」が保持するロックのために実行できません。

ロック テストは 1 つのスレッド内で実行できますが、デッドロック テストは、両方の接続で同時にコマンドを実行しようとする必要があることを意味します。これは、1 つのプログラムではスレッド化なしでは実行できません。

デビッド J.

于 2015-08-31T14:03:15.423 に答える