Introduction to Transactions
A transaction is a mechanism for grouping a set of statements together as a unit. A transaction should be atomic, consistent, independent, and durable (ACID). Depending on the application, this capability can be extremely important.
As an example of the importance of a transaction's ACID properties, consider the elements of a bank transaction. Let's say that you wish to move money from a checking account into a savings account, using the conceptual tasks:
Verify that checking account has more than $100. Remove $100 from checking account. Add $100 to savings account.
These three statements should be thought of as comprising one transaction, and therefore a failure in any of the three steps means that all of them should be ignored. For example, a failure to add $100 to the savings account means that the $100 should not be removed from the checking account.
This leads to a key aspect of any transaction. A transaction can be started and then either committed if there are no problems or rolled back if there is a problem. A transaction that is rolled back should have no impact on the data in the database.
Hibernate supports transactions, but does not actually provide the transaction implementation. Typically, this functionality is provided by the underlying database. To enable this functionality, the hibernate.transaction.factory_class. property should be set to net.sf.hibernate.transaction.JDBCTransactionFactory. Before relying on JDBC transactions, you should check your database's documentation for more information about transaction support.
|
In addition to JDBC transactions, Hibernate also supports the use of JTA. To use JTA, set the hibernate.transaction.factory_class to net.sf.hibernate.transaction.JTATransactionFactory. You will also need to set the JTA transaction manager to the appropriate provider, as described in Chapter 6, Table 6.6.
As a general guide, your environment may require the use of JTA if you are accessing multiple databases or have complex transactions spanning multiple systems (for example, distributed objects using EJB), but it may add significant overhead if you are not.
For more information on JTA, see your application server's documentation. |
Sessions, Transactions, and Flushing
Hibernate uses several terms to describe the logical phases of database interaction. Figure 9.1 illustrates the relationship between a session, a transaction, and a flush.

A session is a lightweight object, representing a JDBC connection.
A transaction represents an ACID unit of work (with the precise meaning dependent on the underlying database and/or transaction manager).
A flush statement may be used to indicate a specific ordering of the execution of a set of SQL. Certain session methods will cause a flush to occur automatically:
Certain calls to Session.find() or Session.iterate() net.sf.hibernate.Transaction.commit() net.sf.hibernate.Session.flush()
Unless a Session.flush() statement is used to override the statement ordering, Hibernate will execute SQL statements in the following order:
Collection element deletions, updates, and insertions
Within each of these broad operational types, the SQL is executed in the same order in which the method calls are made. For example, consider the following operations:
Session.update(object1); Session.delete(object2); Session.update(object3);
When Hibernate translates these operations into SQL, it will first issue SQL to UPDATE the object1 and object3 records, and then DELETE the object2 record.
Under certain circumstances, Hibernate may optimize the generated SQL. In most cases this is the most desirable (and best-performing) behavior, but there are situations (for example, if you have certain database triggers) in which it might be preferable to use a Session.flush() statement to ensure the proper execution of statements.
An exception is that the Session.save() method is called when objects using native generator are inserted.
 |