BUG #10847: Connection.setSavepoint()/releaseSavepoint() is not thread-safe - Mailing list pgsql-bugs
From | christian@schlichtherle.de |
---|---|
Subject | BUG #10847: Connection.setSavepoint()/releaseSavepoint() is not thread-safe |
Date | |
Msg-id | 20140703075343.5122.97077@wrigleys.postgresql.org Whole thread Raw |
Responses |
Re: BUG #10847: Connection.setSavepoint()/releaseSavepoint() is not thread-safe
|
List | pgsql-bugs |
The following bug has been logged on the website: Bug reference: 10847 Logged by: Christian Schlichtherle Email address: christian@schlichtherle.de PostgreSQL version: 9.3.4 Operating system: OS X 10.9.3 Description: I am not sure if this is a bug or a feature. One might argue that you shouldn't share a connection between threads. Anyway, following is a standalone test to reproduce the issue in PostgreSQL 9.3.4 using the JDBC driver version 9.3-1101-jdbc41: <pre><code> package cpssd.db; import org.junit.Test; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Savepoint; import java.util.concurrent.CountDownLatch; /** @author Christian Schlichtherle */ public class Ticket251IT { private static final String CONNECTION_STRING = "jdbc:postgresql:postgres"; private static final int NUM_THREADS = 2; @Test public void foo() throws SQLException, InterruptedException { try (Connection c = DriverManager.getConnection(CONNECTION_STRING)) { c.setAutoCommit(false); final Runnable task = new Runnable() { final CountDownLatch startSignal = new CountDownLatch(NUM_THREADS); @Override public void run() { try { startSignal.countDown(); startSignal.await(); // FIXME: This idiom doesn't work on a shared connection! Savepoint sp = c.setSavepoint(); try { // Insert transaction script here... } finally { c.releaseSavepoint(sp); } } catch (SQLException | InterruptedException e) { e.printStackTrace(); } } }; final Thread[] threads = new Thread[NUM_THREADS]; for (int i = 0; i < threads.length; i++) (threads[i] = new Thread(task)).start(); for (Thread thread : threads) thread.join(); }, } } </code></pre> When run, this code frequently outputs the following stack trace: <pre><code> org.postgresql.util.PSQLException: ERROR: no such savepoint at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2161) at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1890) at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:255) at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:559) at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:403) at org.postgresql.jdbc2.AbstractJdbc2Connection.execSQLUpdate(AbstractJdbc2Connection.java:376) at org.postgresql.jdbc3.AbstractJdbc3Connection.releaseSavepoint(AbstractJdbc3Connection.java:192) at cpssd.db.Ticket251IT$1.run(Ticket251IT.java:32) at java.lang.Thread.run(Thread.java:745) </code></pre>
pgsql-bugs by date: