BUG #10847: Connection.setSavepoint()/releaseSavepoint() is not thread-safe

Started by Nonamealmost 12 years ago3 messagesbugs
Jump to latest
#1Noname
christian@schlichtherle.de

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>

--
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

#2Bruce Momjian
bruce@momjian.us
In reply to: Noname (#1)
Re: BUG #10847: Connection.setSavepoint()/releaseSavepoint() is not thread-safe

I think you need to report this to the JDBC mailing list at
pgsql-jdbc@postgresql.org

http://www.postgresql.org/list/pgsql-jdbc/

The Postgres libpq interface is most definitely not threadsafe but I
don't see any indication in that stack trace that it's using libpq. It
seems to be pure Java there.

--
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

#3John R Pierce
pierce@hogranch.com
In reply to: Bruce Momjian (#2)
Re: BUG #10847: Connection.setSavepoint()/releaseSavepoint() is not thread-safe

On 7/3/2014 11:54 AM, Greg Stark wrote:

I think you need to report this to the JDBC mailing list at
pgsql-jdbc@postgresql.org

http://www.postgresql.org/list/pgsql-jdbc/

The Postgres libpq interface is most definitely not threadsafe but I
don't see any indication in that stack trace that it's using libpq. It
seems to be pure Java there.

yes, the jdbc driver is pure java. you still should avoid using a jdbc
sql connection from more than one thread on the same transaction. its
fine to reuse a connection between transactions as long as only one
thread is using it at a time.

--
john r pierce 37N 122W
somewhere on the middle of the left coast

--
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs