开发者

Turn on Autocommit for simple Pojo data objects?

In my application I have hidden the underlying storage objects behind interfaces, allowing me to switch storage at will.

The issue is that when testing hibernate it seems that Hibernate is very Transaction oriented. Everything that I could find on the subject (mainly their official docs) says that autocommit is bad and should rarely be used. However my entire application isn't written around Hibernate, its written around the interfaces. This means that getting data from the database happens in one 开发者_JAVA百科method (eg getObjects() in the factory), not a Transaction.

Since I've abstracted away the storage implementation, is autocommit the right solution? Or is there an alternative?


The use of auto-commit, does not mean that transactions are no longer used to access data. It simply means that each statement now executes in it's own transaction. The exact instances when the transaction starts and terminates in defined in the JDBC specification. For the sake of brevity, this usually depends on the nature of the statement executed.

I'm not sure of how your design is implemented, but non-transactional systems typically suffer from three problems. The use of auto-commit may reintroduce one or more of these problems.

Dirty reads

Consider a thread A in your application that would read an entity and update it, but not commit the new value. Consider another thread B that reads the same entity and sees the updated value. If thread A were to roll back it's changes, or fail in committing the updated value, then B is essentially using a dirty value, for it performed a dirty read.

On it's own auto-commit does not result in dirty reads. However, if you have a sequence of database read-writes that were originally performed in a single transaction, making the sequence commit after every read/write operation, will result in dirty reads in a different transaction, for your current transaction might simply roll back the change.

Non-repeatable reads

In the context of a transaction, reading the same entity (record) twice in the context of a transaction, and seeing a different value on the second read is considered a non-repeatable read. This occurs when a different transaction has committed it's change and an ongoing transaction reads the new value.

Using auto-commit (or rather performing the read operations in two different transactions) will most likely result in non-repeatable reads, since both the read operations in the same thread will be execute in different transactional contexts, resulting in the second read seeing the committed value (from the transaction in a different thread).

Phantom reads

Very similar to non-repeatable reads, but not quite. In this case, the thread of execution performing the second read, will see additional data (and not updated data) in the form of new records.

Likewise, using auto-commit will most likely result in phantom reads in your application for the same reasons.

These issues will also depend on the database transaction isolation levels employed, but eventually when one uses an ORM framework, marking the start and end of transactions would be left to an application developer. While individual read-write operations may be isolated from each other by the database, it is upto the developer to ensure that work occurs in a transactional context. Using auto-commit changes the transaction context for every operation.

TLDR

Using auto-commit when performing transactional activities would mean that it is impossible to perform a rollback to a safe state, in the event of a failure during a "business transaction context". As an aside, it is for this reason that auto-commits should be disabled when performing batch updates in JDBC. Using auto-commit will force a commit to occur for every update in the batch, when the real need is to commit at the end of the batch.

I would recommend reading the book Java Transaction Design Strategies (available as a free ebook) to gain further insight into using transactions.


There is certainly a property 'hibernate.connection.autocommit' that you can set to true either in your hibernate config XML or programatically on your SessionFactory.

It is not clear from your question what benefit that would really offer you over just beginning and committing a transaction inside your Hibernate implementation of the getObjects() interface method.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜