Why is "hibernate.connection.autocommit = true" not recommended in Hibernate?

72,527

Solution 1

All database statements are executed within the context of a physical transaction, even when we don’t explicitly declare transaction boundaries (BEGIN/COMMIT/ROLLBACK).

If you don't declare the transaction boundaries, then each statement will have to be executed in a separate transaction. This may even lead to opening and closing one connection per statement.

Declaring a service as @Transactional will give you one connection for the whole transaction duration, and all statements will use that single isolation connection. This is way better than not using explicit transactions in the first place. On large applications you may have many concurrent requests and reducing the database connection acquiring request rate is definitely improving your overall application performance.

So the rule of thumb is:

  1. If you have read-only transactions that only execute one query, you can enable auto-commit for those.

  2. If you have transactions containing more than one statement, you need to disable auto-commit, since you want all operations to execute in a single unit-of-work and you don't want to put extra pressure on your connection pool.

Solution 2

By default the autocommit value is false, therefore the transaction needs to be commited explicitly. This might be the reason why the changes not getting reflected in database, else can try flush to force the changes before commit.

When you close the session, then it will get commited in database implicitly [depends on the implementation].

When you have cascading transactions & needs to rollback for atomicity, you need to have control over transactions & in that case, autocommit should be false.

Either set autocommit as true or handle transactions explicitly.

Here is a good explanation on it.

Hibernate forum related to this.

Stackoverflow question on it.

Solution 3

My understanding is that if Hibernate autocommits, then a flush that fails part way through won't be rolled back. You'll have an incomplete/broken object graph.

If you want a connection with autocommit on for something, you can always unwrap a newly created Session to get the underlying JDBC Connection, setAutocommit(true) on it, do your work via JDBC APIs, setAutocommit(false), and close the session. I would not recommend doing this on a Session that's already done anything.

Solution 4

Do not use the session-per-operation antipattern: do not open and close a Session for every simple database call in a single thread. The same is true for database transactions. Database calls in an application are made using a planned sequence; they are grouped into atomic units of work. This also means that auto-commit after every single SQL statement is useless in an application as this mode is intended for ad-hoc SQL console work. Hibernate disables, or expects the application server to disable, auto-commit mode immediately. Database transactions are never optional. All communication with a database has to occur inside a transaction. Auto-commit behavior for reading data should be avoided, as many small transactions are unlikely to perform better than one clearly defined unit of work. The latter is also more maintainable and extensible.

find more information on this topic

Share:
72,527

Related videos on Youtube

Ponmudi VN
Author by

Ponmudi VN

An enthusiastic software engineer :)

Updated on January 10, 2021

Comments

  • Ponmudi VN
    Ponmudi VN over 3 years

    In Hibernate API, there is a property hibernate.connection.autocommit which can be set to true.

    But in the API, they have mentioned that it is not recommended to set it like so:

    Enables autocommit for JDBC pooled connections (it is not recommended).

    Why is it not recommended ? What are the ill-effects of setting this property to true ?

  • Karan Kaw
    Karan Kaw about 7 years
    hibernate uses JDBC under hood. 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. We want- either all statements run or none runs - for that we need to mark beginning and end of transaction and we need to disable autoCommit.
  • Karan Kaw
    Karan Kaw about 7 years
    hibernate.connection.autocommit = false 2 Scenarios Explicit Transaction boundary : sessionFactory.openSession() session.beginTransaction() session.getTransaction().commit()//Flushes Session, Commits Txn session.close() Implicit Transaction boundary sessionFactory.openSession() //See no transaction usage, //but its implicit txn because - Autocommit is false session.flush() session.close() Here - When we close session, Specification is not clear so vendor specific behaviour in Oracle - all sql statements get committed in postgresql - all sql statements rollbacked