📜 ⬆️ ⬇️

Hibernate Developer Documentation - Chapter II. Transactions and multithreading

I present to you the translation of the second chapter of the official documentation Hibernate .

Article translation is relevant for the version Hibernate 4.2.19.Final

Content
')
2.1. Transaction definition
2.2. Physical transactions
2.2.1. Physical Transactions - JDBC
2.2.2. Physical Transactions - JTA
2.2.3. Physical Transactions - CMT
2.2.4. Physical Transactions - Other
2.2.5. Physical Transactions - Legacy
2.3. Hibernate transaction application
2.4. Patterns and anti-transaction patterns
2.4.1. Session-to-operation anti-pattern
2.4.2. Session-to-request pattern
2.4.3. Conversations (Conversations)
2.5. Object identity
2.6. General issues

2.1. Transaction definition


It is important to understand that the term “transaction” has many meanings in relation to persistence and object-relational projection.
In most, but not all cases, the following definitions are appropriate.

Important
This documentation considers the logical and physical concepts of a transaction as one concept.


2.2. Physical transactions


Hibernate uses the JDBC API for persistence. In the Java world, there are two well-defined transaction mechanisms: JDBC and JTA directly. Hibernate supports both transaction integration mechanisms and allows applications to manage physical transactions.

The first concept in understanding Hibernate transaction support is the org.hibernate.engine.transaction.spi.TransactionFactory interface, which provides two main functions:

Important
javax.persistence.EntityTransaction is available only when you use resource-local transactions. Hibernate provides access to org.hibernate.Transaction regardless of the environment.

org.hibernate.engine.transaction.spi.TransactionFactory is a standard Hibernate service. See Details in section 7.5.16, “org.hibernate.engine.transaction.spi.TransactionFactory” .

2.2.1. Physical Transactions - JDBC


Transaction management using JDBC is achieved by the methods java.sql.Connection.commit () and java.sql.Connection.rollback () (JDBC does not define an explicit method for initiating a transaction). In Hibernate, this approach is represented by the class org.hibernate.engine.transaction.internal.jdbc.JdbcTransactionFactory

2.2.2. Physical Transactions - JTA


JTA-approach to transactions is achieved by the javax.transaction.UserTransaction interface, obtained from the org.hibernate.service.jta.platform.spi.JtaPlatform API. This approach is represented by the org.hibernate.engine.transaction.internal.jta.JtaTransactionFactory class .
See JTA Integration Section 7.5.9, “org.hibernate.service.jta.platform.spi.JtaPlatform”

2.2.3. Physical Transactions - CMT


Another JTA-based transaction approach uses the javax.transaction.TransactionManager interface, obtained from the org.hibernate.service.jta.platform.spi.JtaPlatform API. This approach is represented by the org.hibernate.engine.transaction.internal.jta.CMTTransactionFactory class. In the current environment of JEE CM, access to javax.transaction.UserTransaction is closed.
Important
The term CMT is potentially misleading. The important part is that the physical JTA transactions are managed by some other means other than the Hibernate API.

See on JTA integration section 7.5.9, “org.hibernate.service.jta.platform.spi.JtaPlatform” .

2.2.4. Physical Transactions - Other


It is also possible to connect a custom transaction management solution by implementing the org.hibernate.engine.transaction.spi.TransactionFactory contract. The initiator of the default service has built-in support for recognizing custom solutions through hibernate.transaction.factory_class , which may indicate:


2.2.5. Physical Transactions - Legacy


Most of those classes mentioned above were migrated to new packages during development version 4.0. To help with upgrading to a new version, Hibernate will recognize obsolete names for a short period of time.


2.3. Hibernate transaction application


Hibernate uses JDBC connections and JTA resources directly, with no additional synchronization logic. It is important for you to become familiar with JDBC, ANSI SQL, and the specifics of transaction isolation in your DBMS.
Hibernate does not synchronize on objects in memory. The behavior determined by the isolation level of your DB transactions does not change when you use Hibernate. The org.hibernate.Session object acts as a repeatable reads and cache requests that are limited to the limits of the transaction.

Important
To reduce blocking competition, transactions should be as short as possible. Long transactions make it difficult to scale your application to high loads. You do not need to keep transactions open while the end user is working; you need to open them after the user has finished working. This concept is also differently called transactional write-behind.


2.4. Patterns and anti-transaction patterns


2.4.1. Session-to-operation anti-pattern


This is an anti-pattern for opening and closing a Session object for each operation to the database in one thread. It is also an anti-pattern in terms of database transactions. Group your calls into one scheduled sequence. Also, do not auto-commit transactions per SQL statement. Hibernate turns off, or expects the application server to turn off auto-commit mode immediately. Transactions to the database have never been optional. All communications with the database must be wrapped in a transaction. Avoid auto-commit when reading data, because quite rarely a lot of small transactions will work faster than one properly defined transaction. Moreover, such a multitude of transactions is difficult to maintain and expand.
Important
The use of autocommit does not necessarily lead to the use of database transactions for each expression. Instead, in autocommit mode, JDBC drivers simply make each call as part of an implicit transaction call. This is the same as if your application made a commit () transaction call after each JDBC call.

2.4.2. Session-to-request pattern


The most common transaction pattern. The term “request” here should be understood in the context of a system that responds to a series of requests from a user / client. Web applications are a prime example of such systems, but, of course, they are not the only ones. At the stage of starting the processing of a request, the application opens the Session object, initiates a transaction, does all the related work with the data, completes the transaction and closes the Session . The essence of the pattern is a one-to-one relationship between a transaction and a session.
As part of the pattern, there is a common technique for determining the current session to simplify the transfer of this Session between application components. Hibernate provides support for this technique through the getCurrentSession () method of the SessionFactory class. The concept of a “current” session should have a scope that defines the boundaries in which the definition of “current” is true. This is the task of the org.hibernate.context.spi.CurrentSessionContext contract. There are two reliably defined scopes:

Important
The getCurrentSession () method has one nasty side in JTA. If you use it, the after_statement connection release mode will also be used by default. Due to limitations of JTA, Hibernate cannot automatically clean up any unclosed instance of ScrollableResults or Iterator returned by scroll () or iterate () . The release of DB cursors is done by calling ScrollableResults.close () or Hibernate.close (Iterator) explicitly from the finally section.

2.4.3. Dialogues


Session-to-request pattern is not the only unit of work design tool. Many business processes require a whole series of user interactions that alternate with access to the database. In web and enterprise applications, it is unacceptable for a database transaction to cover all user interaction. Consider the following example:

Procedure 2.1. Example of “long-playing” dialogue
  1. The first screen of the dialog opens. The data shown to the user is loaded in a separate session session and database transaction. The user can modify any dialog fields.
  2. After five minutes of editing, the user uses the UI element to save. Changes are reflected in the database. The user also expects exclusive data access during the editing session.


Even though we have several cases of access to the database, from the user's point of view, this series of steps represents one unit of perfect work (Unit of Work). There are many ways to implement this in an application.

The first (naive) method is to keep Session sessions and transactions open while the user is editing, using database synchronization mechanisms to provide exclusive user access to editable data, and prevent other users from accessing them, ensuring isolation and atomicity. This is an anti-pattern, since unnecessary synchronization is a bottleneck for performance problems arising in high-load applications.

A number of database transactions is used to implement a dialogue with the database. In this case, ensuring the isolation of business processes falls on the shoulders of the application. One conversation usually covers multiple transactions. Multiple database accesses can be atomic if only one transaction (usually the last one) writes to the database. All others only read the data. A typical implementation path is through the creation of a wizard-style dialog covering several steps of a request / response cycle. Hibernate includes some features that allow you to implement similar functionality.


Session-to-request-with-disconnected-objects and session-to-dialogue have their pros and cons.

2.5. Object identity


An application can simultaneously access the same persistent state (a string in a database) in two different sessions. However, an instance of a persistent class is never split between two different sessions. Two different notions of identity take place and come into play: DB-identity and JVM-identity.

Example 2.1. DB identity
foo.getId().equals( bar.getId() ) 


Example 2.2. JVM Identity
 foo==bar 


For objects attached to the same Session session, two identity concepts are equivalent, and JVM identity is guaranteed by the Hibernate database identity. An application can simultaneously access a business object with the same database identity in two different sessions; meanwhile, it will be represented by two different instances of Java objects, in terms of JVM identity. Conflict resolution is performed by optimistic strategy and automatic versioning during flush / commit.

This approach places the responsibility for managing concurrency on Hibernate and the database. It also provides better scalability, since expensive locks are not needed to guarantee identity in a single-threaded unit of work (single-threaded unit of work). There is no need for the application to synchronize on any business object while it is running in one thread. Although not recommended, within an Session session, an application can safely use the == operator to compare objects.

However, an application using the == operator outside a session can introduce some problems. If you add two detached instances of an object to the same Set, they will probably have the same database identity, that is, they represent the same row in the table. It is not at all guaranteed that they will have the same JVM identity, being able to be detached. Override the equals () and hashCode () methods in persistent classes so that they have their own definition of object equivalence. Do not use the identity database to implement the equality test. Instead, use a business key that is a combination of unique, immutable attributes. The database identifier may change if the object changes from the transient state to the persistent state. If a transient instance is found with the detached instance in the same Set'e - changing the hashcode will violate the Set'a contract. Attributes for a business key may be less robust than basic keys. You only need to guarantee stability as long as the objects are in the same Set. This is not a Hibernate problem, as it relates to the implementation of object identity and equivalence in Java.

2.6. General issues


Both session-per-session-user and session-per-application anti-patterns are susceptible to the following issues. Some of these problems may also occur in the recommended patterns, so first make sure that you understand the implications before making any design decisions:

Source: https://habr.com/ru/post/269485/


All Articles