Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

executeBatch(...) hangs indefinitely with no exception #3199

Open
MartinHaeusler opened this issue Apr 10, 2024 · 1 comment
Open

executeBatch(...) hangs indefinitely with no exception #3199

MartinHaeusler opened this issue Apr 10, 2024 · 1 comment

Comments

@MartinHaeusler
Copy link

Please read https://stackoverflow.com/help/minimal-reproducible-example

Describe the issue
My application inserts rows via PreparedStatement.executeBatch(...). In some cases, this call never returns and blocks indefinitely.

Driver Version?
42.7.3

Java Version?
17.0.10

OS Version?
Alpine 3.19

PostgreSQL Version?
15.6

To Reproduce

// MyTable has a combined primary key consisting of (column2, column4, column5, column6)
// column1 is a timestamp, the rest are varchar(255)
private static final String SQL_INSERT = """
  INSERT 
      INTO MyTable(column1, column2, column3, column4, column5, column6) 
      VALUES (?, ?, ?, ?, ?, ?)
  ON CONFLICT(column2, column4, column5, column6) DO UPDATE
      SET column1 = EXCLUDED.column1,
          column2 = EXCLUDED.column2,
          column3 = EXCLUDED.column3,
          column4 = EXCLUDED.column4,
          column5 = EXCLUDED.column5,
          column6 = EXCLUDED.column6
  ;
""";

public void performInserts(Connection c, Iterable<SomeDataClass> elementsToInsert){
  try(var pStmt = c.prepareStatement(SQL_INSERT)){
      for(element in elementsToInsert){
          pStmt.setLong(1, elementToInsert.getLongValue());
          pStmt.setString(2, elementToInsert.getStringValue1());
          pStmt.setString(3, elementToInsert.getStringValue2());
          pStmt.setString(4, elementToInsert.getStringValue3());
          pStmt.setString(5, elementToInsert.getStringValue4());
          pStmt.setString(6, elementToInsert.getStringValue5());
          pStmt.addBatch();
      }
      pStmt.executeBatch();
  }
}

Expected behaviour
I would expect the insert to be executed and the method to return successfully.

Logs

This is the thread stack we're seeing:

"pool-5-thread-1" 
   java.lang.Thread.State: RUNNABLE
        at java.base@17.0.10/sun.nio.ch.Net.poll(Native Method)
        at java.base@17.0.10/sun.nio.ch.NioSocketImpl.park(NioSocketImpl.java:186)
        at java.base@17.0.10/sun.nio.ch.NioSocketImpl.park(NioSocketImpl.java:195)
        at java.base@17.0.10/sun.nio.ch.NioSocketImpl.implRead(NioSocketImpl.java:319)
        at java.base@17.0.10/sun.nio.ch.NioSocketImpl.read(NioSocketImpl.java:355)
        at java.base@17.0.10/sun.nio.ch.NioSocketImpl$1.read(NioSocketImpl.java:808)
        at java.base@17.0.10/java.net.Socket$SocketInputStream.read(Socket.java:966)
        at org.postgresql.core.VisibleBufferedInputStream.readMore(VisibleBufferedInputStream.java:161)
        at org.postgresql.core.VisibleBufferedInputStream.ensureBytes(VisibleBufferedInputStream.java:128)
        at org.postgresql.core.VisibleBufferedInputStream.ensureBytes(VisibleBufferedInputStream.java:113)
        at org.postgresql.core.VisibleBufferedInputStream.read(VisibleBufferedInputStream.java:73)
        at org.postgresql.core.PGStream.receiveChar(PGStream.java:465)
        at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2154)
        at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2133)
        at org.postgresql.core.v3.QueryExecutorImpl.flushIfDeadlockRisk(QueryExecutorImpl.java:1490)
        at org.postgresql.core.v3.QueryExecutorImpl.sendQuery(QueryExecutorImpl.java:1515)
        at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:559)
        at org.postgresql.jdbc.PgStatement.internalExecuteBatch(PgStatement.java:896)
        at org.postgresql.jdbc.PgStatement.executeBatch(PgStatement.java:919)
        at org.postgresql.jdbc.PgPreparedStatement.executeBatch(PgPreparedStatement.java:1677)
        at com.mycompany.MyService.performInserts(MyService.java)

This stack trace will remain the same for extended periods of time (minutes). I do not know exactly how many elements are in the batch, but I suspect no more than 1000 at most.

@davecramer
Copy link
Member

see #194

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants