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

Поиск
Список
Период
Сортировка
От christian@schlichtherle.de
Тема BUG #10847: Connection.setSavepoint()/releaseSavepoint() is not thread-safe
Дата
Msg-id 20140703075343.5122.97077@wrigleys.postgresql.org
обсуждение исходный текст
Ответы Re: BUG #10847: Connection.setSavepoint()/releaseSavepoint() is not thread-safe  (Greg Stark <stark@mit.edu>)
Список 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 по дате отправления:

Предыдущее
От: Mark Kirkwood
Дата:
Сообщение: Re: Alter system and reload causes bogus complaints about setting changes
Следующее
От: Jacek Mazurek
Дата:
Сообщение: unattended install error