2012-07-09 3 views
5

Ho qualche strano problema.Il commit automatico passa a VERO dopo un po 'utilizzando un pool di connessioni

Utilizzo un pool per creare e gestire DB Connections, ho impostato l'opzione DefaultAutocommit su FALSE.

Ma dopo un po ', quando si verificano un errore e un rollback è chiamata viene generata un'eccezione: Can't call rollback when autocommit=true

Rilanciare JBoss risolverà il problema come verrà creato un nuovo DataSource.

Ecco come Creo il mio Origine dati:

protected DataSource getDataSource(String driverClassName, String dbUrl, String dbUser, String dbPwd) { 
    PoolProperties poolProperties = new PoolProperties(); 
    poolProperties.setUrl(dbUrl); 
    poolProperties.setDriverClassName(driverClassName); 
    poolProperties.setUsername(dbUser); 
    poolProperties.setPassword(dbPwd); 

    poolProperties.setDefaultAutoCommit(false); 
    poolProperties.setTestWhileIdle(false); 
    poolProperties.setTestOnBorrow(true); 
    poolProperties.setDefaultTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); 
    poolProperties.setValidationQuery("SELECT 1"); 
    poolProperties.setTestOnReturn(false); 
    poolProperties.setLogAbandoned(false); 
    poolProperties.setRemoveAbandoned(true); 
    poolProperties.setRemoveAbandonedTimeout(20); 
    poolProperties.setMaxActive(100); 
    poolProperties.setInitialSize(10); 
    poolProperties.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"); 

    return new DataSource(poolProperties); 
} 

E come ottenere i collegamenti:

xxx.getDataSource().getConnection(); 

Non ho provato ancora, ma la mia prima chiamata sarà quello di forzare l'autocommit direttamente sulla connessione utilizzando setAutoCommit(false).

Anche se non capisco perché lo poolProperties.setDefaultAutoCommit(false); stia terminando di fare il lavoro.

traccia stack:

com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Can't call rollback when autocommit=true 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) 
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) 
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513) 
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:409) 
    at com.mysql.jdbc.Util.getInstance(Util.java:384) 
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1015) 
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:989) 
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:984) 
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:929) 
    at com.mysql.jdbc.ConnectionImpl.rollback(ConnectionImpl.java:4805) 
    at sun.reflect.GeneratedMethodAccessor302.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at org.apache.tomcat.jdbc.pool.ProxyConnection.invoke(ProxyConnection.java:125) 
    at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:94) 
    at org.apache.tomcat.jdbc.pool.interceptor.AbstractCreateStatementInterceptor.invoke(AbstractCreateStatementInterceptor.java:71) 
    at org.apache.tomcat.jdbc.pool.JdbcInterceptor.invoke(JdbcInterceptor.java:94) 
    at org.apache.tomcat.jdbc.pool.interceptor.ConnectionState.invoke(ConnectionState.java:140) 
    at $Proxy333.rollback(Unknown Source) 
+0

Potrebbe fornire analisi dello stack errore? –

+0

Molto probabilmente si tratta di un bug nel pool di connessioni o nel driver JDBC MySQL. A parte questo, penso che questa domanda sia senza risposta. –

+0

@MarkRotteveel Beh, non ho trovato alcuna traccia di un tale errore. Ma proveremo a forzare direttamente l'attributo sulla connessione. Può aiutare altri se questo lavoro. –

risposta

2

: ecco che cosa è a posto oggi, ho forzare l'attributo AutoCommit su ogni connessione creata a bordo piscina.

Questo funziona, quindi potrebbe sicuramente essere un bug delle classi piscina.

Modifica: Ho anche riscontrato un problema con l'isolamento della transazione impostato nello stesso modo ma non preso in considerazione. Dopo alcune ricerche ho scoperto che questo potrebbe essere correlato al connettore Mysql/J che uso (http://dev.mysql.com/doc/refman/5.1/en/connector-j-reference-configuration-properties.html).

ho trovato questo parametro interessante nel documento:

useLocalSessionState

Qualora il conducente riferimento ai valori interni di autocommit e isolamento di transazione che sono impostati da Connection.setAutoCommit() e Connection.setTransactionIsolation() e lo stato della transazione come gestito dal protocollo, anziché interrogare il database o inviare ciecamente comandi al database per commit() o ro llback() chiamate di metodo?

Valore di default: falso