[jira] [Comment Edited] (CALCITE-5009) Make sure transaparent jdbc connection re-creation does not lead to data loss

2022-02-10 Thread Istvan Toth (Jira)


[ 
https://issues.apache.org/jira/browse/CALCITE-5009?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17490697#comment-17490697
 ] 

Istvan Toth edited comment on CALCITE-5009 at 2/11/22, 7:00 AM:


Ultimately, Connection#createStatement()
{noformat}
  org.apache.calcite.avatica.AvaticaClientRuntimeException: Remote driver 
error: 
  RuntimeException: Connection already exists: 
e1cbaa54-dd66-461e-8bee-15d6a6296581 at 
  
org.apache.calcite.avatica.remote.Service$ErrorResponse.toException(Service.java:2475)
 at 
  
org.apache.calcite.avatica.remote.RemoteProtobufService._apply(RemoteProtobufService.java:62)
 at 
  
org.apache.calcite.avatica.remote.ProtobufService.apply(ProtobufService.java:81)
 at 
  org.apache.calcite.avatica.remote.RemoteMeta$3.call(RemoteMeta.java:114) at 
  org.apache.calcite.avatica.remote.RemoteMeta$3.call(RemoteMeta.java:110) at 
  
org.apache.calcite.avatica.AvaticaConnection.invokeWithRetries(AvaticaConnection.java:793)
 at 
  
org.apache.calcite.avatica.remote.RemoteMeta.openConnection(RemoteMeta.java:109)
 at 
  
org.apache.calcite.avatica.AvaticaConnection.openConnection(AvaticaConnection.java:154)
 at 
  
org.apache.calcite.avatica.AvaticaConnection.invokeWithRetries(AvaticaConnection.java:797)
 at 
  
org.apache.calcite.avatica.remote.RemoteMeta.connectionSync(RemoteMeta.java:134)
 at 
  org.apache.calcite.avatica.remote.RemoteMeta$1.call(RemoteMeta.java:88) at 
  org.apache.calcite.avatica.remote.RemoteMeta$1.call(RemoteMeta.java:85) at 
  
org.apache.calcite.avatica.AvaticaConnection.invokeWithRetries(AvaticaConnection.java:793)
 at 
  
org.apache.calcite.avatica.remote.RemoteMeta.createStatement(RemoteMeta.java:84)
 at 
  org.apache.calcite.avatica.AvaticaStatement.(AvaticaStatement.java:115) 
at 
  org.apache.calcite.avatica.AvaticaStatement.(AvaticaStatement.java:101) 
at
  
org.apache.calcite.avatica.AvaticaJdbc41Factory$AvaticaJdbc41Statement.(AvaticaJdbc41Factory.java:118)
 at 
  
org.apache.calcite.avatica.AvaticaJdbc41Factory$AvaticaJdbc41Statement.(AvaticaJdbc41Factory.java:114)
 at 
  
org.apache.calcite.avatica.AvaticaJdbc41Factory.newStatement(AvaticaJdbc41Factory.java:76)
 at 
  
org.apache.calcite.avatica.AvaticaConnection.createStatement(AvaticaConnection.java:343)
 at 
  
org.apache.calcite.avatica.AvaticaConnection.createStatement(AvaticaConnection.java:167)
 at 
  
org.apache.calcite.avatica.AvaticaConnection.createStatement(AvaticaConnection.java:63)
 at
  org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:379) at 
 {noformat}
The "Connection already exists" exception is the original problem that I was 
investigating.
I think that it happens above is that as the server side connection is expired, 
multiple client threads try to re-create the connection, and we run into a race 
condition.
While could probably do something  about that race condition (like 
synchronizing the reconnect code), that is a relatively harmless issue.

The more serious problem is that we break transaction handling, which depends 
on the proxied connection object being tightly controlled by the application.

Breaking transactions is the most obvious problem caused by replacing the 
proxied connection object on the sly, but there may be more, mysql's 
LAST_INSERT_ID comes to my mind that may be lost in this case.

We should also check if we do similar transaparent re-create for statement 
objects, and if we do, what, if any problems does that cause.


was (Author: stoty):
Ultimately, createConnection()
{noformat}
  org.apache.calcite.avatica.AvaticaClientRuntimeException: Remote driver 
error: 
  RuntimeException: Connection already exists: 
e1cbaa54-dd66-461e-8bee-15d6a6296581 at 
  
org.apache.calcite.avatica.remote.Service$ErrorResponse.toException(Service.java:2475)
 at 
  
org.apache.calcite.avatica.remote.RemoteProtobufService._apply(RemoteProtobufService.java:62)
 at 
  
org.apache.calcite.avatica.remote.ProtobufService.apply(ProtobufService.java:81)
 at 
  org.apache.calcite.avatica.remote.RemoteMeta$3.call(RemoteMeta.java:114) at 
  org.apache.calcite.avatica.remote.RemoteMeta$3.call(RemoteMeta.java:110) at 
  
org.apache.calcite.avatica.AvaticaConnection.invokeWithRetries(AvaticaConnection.java:793)
 at 
  
org.apache.calcite.avatica.remote.RemoteMeta.openConnection(RemoteMeta.java:109)
 at 
  
org.apache.calcite.avatica.AvaticaConnection.openConnection(AvaticaConnection.java:154)
 at 
  
org.apache.calcite.avatica.AvaticaConnection.invokeWithRetries(AvaticaConnection.java:797)
 at 
  
org.apache.calcite.avatica.remote.RemoteMeta.connectionSync(RemoteMeta.java:134)
 at 
  org.apache.calcite.avatica.remote.RemoteMeta$1.call(RemoteMeta.java:88) at 
  org.apache.calcite.avatica.remote.RemoteMeta$1.call(RemoteMeta.java:85) at 
  
org.apache.calcite.avatica.AvaticaConnection.invokeWithRetries(AvaticaConnection.java:793)
 at 
  

[jira] [Comment Edited] (CALCITE-5009) Make sure transaparent jdbc connection re-creation does not lead to data loss

2022-02-10 Thread Istvan Toth (Jira)


[ 
https://issues.apache.org/jira/browse/CALCITE-5009?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=17490697#comment-17490697
 ] 

Istvan Toth edited comment on CALCITE-5009 at 2/11/22, 7:00 AM:


Ultimately, createConnection()
{noformat}
  org.apache.calcite.avatica.AvaticaClientRuntimeException: Remote driver 
error: 
  RuntimeException: Connection already exists: 
e1cbaa54-dd66-461e-8bee-15d6a6296581 at 
  
org.apache.calcite.avatica.remote.Service$ErrorResponse.toException(Service.java:2475)
 at 
  
org.apache.calcite.avatica.remote.RemoteProtobufService._apply(RemoteProtobufService.java:62)
 at 
  
org.apache.calcite.avatica.remote.ProtobufService.apply(ProtobufService.java:81)
 at 
  org.apache.calcite.avatica.remote.RemoteMeta$3.call(RemoteMeta.java:114) at 
  org.apache.calcite.avatica.remote.RemoteMeta$3.call(RemoteMeta.java:110) at 
  
org.apache.calcite.avatica.AvaticaConnection.invokeWithRetries(AvaticaConnection.java:793)
 at 
  
org.apache.calcite.avatica.remote.RemoteMeta.openConnection(RemoteMeta.java:109)
 at 
  
org.apache.calcite.avatica.AvaticaConnection.openConnection(AvaticaConnection.java:154)
 at 
  
org.apache.calcite.avatica.AvaticaConnection.invokeWithRetries(AvaticaConnection.java:797)
 at 
  
org.apache.calcite.avatica.remote.RemoteMeta.connectionSync(RemoteMeta.java:134)
 at 
  org.apache.calcite.avatica.remote.RemoteMeta$1.call(RemoteMeta.java:88) at 
  org.apache.calcite.avatica.remote.RemoteMeta$1.call(RemoteMeta.java:85) at 
  
org.apache.calcite.avatica.AvaticaConnection.invokeWithRetries(AvaticaConnection.java:793)
 at 
  
org.apache.calcite.avatica.remote.RemoteMeta.createStatement(RemoteMeta.java:84)
 at 
  org.apache.calcite.avatica.AvaticaStatement.(AvaticaStatement.java:115) 
at 
  org.apache.calcite.avatica.AvaticaStatement.(AvaticaStatement.java:101) 
at
  
org.apache.calcite.avatica.AvaticaJdbc41Factory$AvaticaJdbc41Statement.(AvaticaJdbc41Factory.java:118)
 at 
  
org.apache.calcite.avatica.AvaticaJdbc41Factory$AvaticaJdbc41Statement.(AvaticaJdbc41Factory.java:114)
 at 
  
org.apache.calcite.avatica.AvaticaJdbc41Factory.newStatement(AvaticaJdbc41Factory.java:76)
 at 
  
org.apache.calcite.avatica.AvaticaConnection.createStatement(AvaticaConnection.java:343)
 at 
  
org.apache.calcite.avatica.AvaticaConnection.createStatement(AvaticaConnection.java:167)
 at 
  
org.apache.calcite.avatica.AvaticaConnection.createStatement(AvaticaConnection.java:63)
 at
  org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:379) at 
 {noformat}

The "Connection already exists" exception is the original problem that I was 
investigating.
I think that it happens above is that as the server side connection is expired, 
multiple client threads try to re-create the connection, and we run into a race 
condition.
While could probably do something  about that race condition (like 
synchronizing the reconnect code), that is a relatively harmless issue.

The more serious problem is that we break transaction handling, which depends 
on the proxied connection object being tightly controlled by the application.

Breaking transactions is the most obvious problem caused by replacing the 
proxied connection object on the sly, but there may be more, mysql's 
LAST_INSERT_ID comes to my mind that may be lost in this case.

We should also check if we do similar transaparent re-create for statement 
objects, and if we do, what, if any problems does that cause.


was (Author: stoty):
Ultimately, createConnection()
{noformat}
  org.apache.calcite.avatica.AvaticaClientRuntimeException: Remote driver 
error: 
  RuntimeException: Connection already exists: 
e1cbaa54-dd66-461e-8bee-15d6a6296581 at 
  
org.apache.calcite.avatica.remote.Service$ErrorResponse.toException(Service.java:2475)
 at 
  
org.apache.calcite.avatica.remote.RemoteProtobufService._apply(RemoteProtobufService.java:62)
 at 
  
org.apache.calcite.avatica.remote.ProtobufService.apply(ProtobufService.java:81)
 at 
  org.apache.calcite.avatica.remote.RemoteMeta$3.call(RemoteMeta.java:114) at 
  org.apache.calcite.avatica.remote.RemoteMeta$3.call(RemoteMeta.java:110) at 
  
org.apache.calcite.avatica.AvaticaConnection.invokeWithRetries(AvaticaConnection.java:793)
 at 
  
org.apache.calcite.avatica.remote.RemoteMeta.openConnection(RemoteMeta.java:109)
 at 
  
org.apache.calcite.avatica.AvaticaConnection.openConnection(AvaticaConnection.java:154)
 at 
  
org.apache.calcite.avatica.AvaticaConnection.invokeWithRetries(AvaticaConnection.java:797)
 at 
  
org.apache.calcite.avatica.remote.RemoteMeta.connectionSync(RemoteMeta.java:134)
 at 
  org.apache.calcite.avatica.remote.RemoteMeta$1.call(RemoteMeta.java:88) at 
  org.apache.calcite.avatica.remote.RemoteMeta$1.call(RemoteMeta.java:85) at 
  
org.apache.calcite.avatica.AvaticaConnection.invokeWithRetries(AvaticaConnection.java:793)
 at