postgresql永远挂起可序列化的事务

时间:2015-08-27 17:11:43

标签: sql postgresql hang libpqxx

我使用libpqxx连接到postgresql。一切都很好,直到我在一行的一张桌子上运行serialazable查询。

表:

CREATE TABLE t1(id integer primary key);

postgres 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函数中。为什么?我认为它必须回滚一个交易吗?但不是?只是挂起。

UPDATE:纯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 - 同样挂起

2 个答案:

答案 0 :(得分:0)

如果仅涉及两个事务,则应该为事务 t2 - 与默认READ COMMITTED隔离级别完全相同的获取唯一的违规错误:

ERROR:  duplicate key value violates unique constraint "t1_pkey"
DETAIL:  Key (id)=(25) already exists.

t1 首先尝试插入并获胜,无论哪个事务首先尝试提交。尝试插入相同密钥的所有后续事务等待第一个。同样,这适用于READ COMMITTEDSERIALIZABLE等。

可能的解释 将涉及第三个交易,它试图先插入相同的密钥并仍然打开。或几个这样的交易,你的测试的人工制品。

所有交易等待第一个试图插入相同密钥的交易。如果那个提交,所有其他人都会获得一次独特的违规行为。如果它回滚,那么下一个就有机会。

查看pg_stat_activity(连接到相同的数据库):

SELECT * FROM pg_stat_activity;

更具体地说:

SELECT * FROM pg_stat_activity WHERE state = 'idle in transaction';

然后提交/回滚空闲事务。或暴力:终止该连接。详细说明:

答案 1 :(得分:0)

组建postgres团队:

“在并发编程中,死锁是指两个或多个竞争行为各自等待另一个完成的情况,因此两者都没有。” https://en.wikipedia.org/wiki/Deadlock

定义它首先不是僵局。 “c1”不等待“c2”完成,并且可以愉快地开展id = 104的业务。但是,你的应用程序永远不会给c1下一个命令,因为它固执地等待“c2”执行它的插入 - 由于“c1”持有锁,它不能。

锁定测试可以在一个线程内完成,但死锁测试意味着两个连接都需要同时尝试执行命令 - 单个程序无法在没有线程的情况下完成。

David J。

相关问题