Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JDBC commit failed, calling commit when autocommit=true. Multithreaded hibernate session somehow changing autocommit?

I have the main thread that spawns thread #2 which uses the same hibernate Session in the main thread. Thread #2 just does a "select 1" every few min to keep the db connection alive because of a long running process from the main thread. Once the main thread is done w/ the processing, it calls a commit but i get the error:

Caused by: org.hibernate.TransactionException: JDBC commit failed
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:161)
    at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:655)
    ... 5 more
Caused by: java.sql.SQLException: Can't call commit when autocommit=true
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:930)
    at com.mysql.jdbc.ConnectionImpl.commit(ConnectionImpl.java:1602)
    at org.hibernate.transaction.JDBCTransaction.commitAndResetAutoCommit(JDBCTransaction.java:170)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:146)
    ... 6 more

Within the main thread, it creates inner transactions which are committed successfully, it's just the outer transaction when it commits that throws this error. I don't see what could be changing the autocommit boolean. Before I introduced the 2nd thread to keep the connection alive, this error had never occurred.

like image 828
czer Avatar asked Mar 10 '11 16:03

czer


People also ask

Does JDBC auto-commit?

By default, JDBC uses an operation mode called auto-commit. This means that every update to the database is immediately made permanent. Any situation where a logical unit of work requires more than one update to the database cannot be done safely in auto-commit mode.

Should Autocommit be true or false?

You should set autocommit to true whenever you're issuing database transactions. A database trasaction is a logical unit of work, which usually consists of multiple database operations (usually multiple updates) and you want either all of them to succeed or all of them to fail.

How do I turn off Autocommit in Java?

However, you can disable auto-commit mode with the setAutoCommit() method of the connection object (either java. sql. Conection or oracle.

What is hibernate auto-commit mode?

autoCommit is a concept of JDBCConnection, which means "Transaction per statement". scope of transactionn = 1 sql statement [autocommit=true] hibernate. connection. autoCommit=true makes each statement Commited once its finished, so we cannot commit/rollback 2 or more statements as a part of single unit of work.


2 Answers

Even though I think you should seriously reconsider the way you are using Hibernate, you can bypass this issue by adding a relaxAutoCommit parameter to the JDBC driver in its URL.

Details from MySQL documentation:

relaxAutoCommit

If the version of MySQL the driver connects to does not support transactions, still allow calls to commit(), rollback() and setAutoCommit() (true/false, defaults to 'false')?

Default: false

Since version: 2.0.13

Source: https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-reference-configuration-properties.html

like image 194
jpkrohling Avatar answered Oct 04 '22 04:10

jpkrohling


found the answer in a blog, the solution quotes:

Setting the attribute relaxAutoCommit=true in the jdbc url we solved our problem.

jdbc:mysql://dbserver/database?rewriteBatchedStatements=true&relaxAutoCommit=true

Of course the blog is in another scenario, just skip the "rewriteBatchedStatements=true" part

like image 40
kkzxak47 Avatar answered Oct 04 '22 04:10

kkzxak47