📜 ⬆️ ⬇️

Hibernate Developer Documentation - Chapter V. Locks

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

Article translation is relevant for the version Hibernate 4.2.19.Final

Previous chapter - Hibernate Developer Documentation - Chapter IV. Batch processing
Next chapter - Hibernate Developer Documentation - Chapter VI. Caching
')
Content
5.1. Optimistic locks
5.1.1 Dedicated version number
5.1.2. Timestamp
5.2. Pessimistic locks

Locks are measures to prevent data from being modified in a relational database between the time it is read and the time it is used.
The blocking strategy can be either optimistic or pessimistic.

Blocking strategies

Optimistic
Optimistic locks assume that multiple transactions can complete without affecting each other, and thus can be executed without locking the resources they affect. Before a commit, each transaction verifies that no other transaction has modified its data. If the check reveals conflicting modifications, the transaction in the commit state is rolled back.

Pessimistic
A pessimistic strategy implies that parallel transactions will conflict with each other, and requires blocking resources after reading them, as well as removing them only after the application has finished using the data.
Hibernate provides mechanisms for implementing both locking strategies in your application.

5.1. Optimistic locks


You can store versioned data when your application uses long-lived transactions or dialogs that span multiple transaction databases. Thus, if the same entity will be modified by two dialogs, the last dialog that commits the changes will be notified of the conflict and will not overwrite the results of another dialog. This approach guarantees a certain degree of isolation, but at the same time it scales well and shows itself quite well in situations of Read-Often Write-Sometimes
Hibernate provides two different mechanisms for storing versioned information — a dedicated version number, or a timestamp .

Version number
Timestamp

Important
The version or timestamp property cannot be null for detached objects. Hibernate recognizes any instance with a version (or timestamp) equal to null as transient , regardless of the other unsaved-value * strategies you specify. Declaring a null version or timestamp property is an easy way to avoid problems with Hibernate's transitive reattachment , which is especially useful in cases where you use assigned identifiers or composite keys.

* unsaved-value - strategy for defining an UPDATE or INSERT operation for synchronization with the database, depending on the value of the property being projected using id, version, or timestamp (approx. transl.)

5.1.1. Dedicated version number


The version number mechanism for optimistic locks is provided by Version annotation.

Example 5.1. Version annotation

@Entity public class Flight implements Serializable { ... @Version @Column(name="OPTLOCK") public Integer getVersion() { ... } } 

Here, the version property is mapped to the OPTLOCK column, and the entity manager ( entity manager ) uses it to identify conflicting updates and prevent the loss of updates that would be overwritten by the last-commit-wins strategy.

The version column can be of any type, provided that you define and implement the appropriate UserVersionType .

Your application is not allowed to change the version number provided by Hibernate. To artificially increase the version number, see the description of the LockModeType.OPTIMISTIC_FORCE_INCREMENT or LockModeType.PESSIMISTIC_FORCE_INCREMENT properties in the Hibernate Entity Manager documentation. If the version number is generated by a database, such as a trigger, use the org.hibernate.annotations.Generated (GenerationTime.ALWAYS) annotation.

Example 5.2. The version property declaration in hbm.xml

 <version column="version_column" name="propertyName" type="typename" access="field|property|ClassName" unsaved-value="null|negative|undefined" generated="never|always" insert="true|false" node="element-name|@attribute-name|element/@attribute|." /> 

NameDescription
columnThe name of the column in which the version number is located.
Optionally, the default is the same as the property name.
nameThe name of the property of the persistent class.
typeType of version number. Optional default integer.
accessHibernate strategy for accessing the property value. Optionally, the default property
unsaved-valueIndicates that the instance has just been created and thus not saved. Distinguishes from detached entities.
The default value, undefined , indicates that the identifier property should not be used. Optional.
generatedIndicates that the version property should be generated by the database.
Optionally, the default is never.
insertInclude or not the version column in the SQL-insert expression. By default, true, but you can set this to false if the column in the database is defined with a default value of 0


5.1.2. Timestamp


Timestamps are a less reliable way to optimize locks than version numbers, which can also be used by applications for other purposes. Time stamps are used automatically if you use the Version annotation on a Date or Calendar property.

Example 5.3. Using timestamps for optimistic locks

 @Entity public class Flight implements Serializable { ... @Version public Date getLastUpdate() { ... } } 

Hibernate can extract the timestamp value from the database or JVM by reading the org.hibernate.annotations.Source annotation value . The value can be either org.hibernate.annotations.SourceType.DB , or org.hibernate.annotations.SourceType.VM . The default behavior is to use a database, also used if you do not specify an annotation.
The timestamp can also be generated by the database instead of Hibernate if you use the org.hibernate.annotations.Generated (GenerationTime.ALWAYS) annotation.

Example 5.4. The timestamp element in hbm.xml

 <timestamp column="timestamp_column" name="propertyName" access="field|property|ClassName" unsaved-value="null|undefined" source="vm|db" generated="never|always" node="element-name|@attribute-name|element/@attribute|." /> 

NameDescription
columnThe name of the column in which the timestamp is located. Optionally, by default
same as property name.
nameThe name of the JavaBeans property of type Date or Timestamp of the persistent property.
accessThe strategy that Hibernate uses to access the value of a property.
Optionally, the default property.
unsaved-valueIndicates that the instance has just been created and thus not saved. Allocates
from detached entities (detached). The default value, undefined, shows
That property-id should not be used. Optional.
sourceWhether Hibernate extracts a tag from the database or from the current JVM. DB labels add an additional overhead, as Hibernate needs to query the database each time to determine the increment.
However, DB labels are safer when used in
clustered environment.
Not all DB dialects support extracting current timestamps from a DB. Others may be unsafe for locks, due to lack of accuracy.
generatedWhether tags are generated by the database. Optionally, the default is never.


5.2. Pessimistic locks


The LockMode class defines the different levels of locks that Hibernate can capture.


The explicit user request indicated above occurs as a result of any of the following:

If you call Session.load () with the UPGRADE or UPGRADE_NOWAIT option, and the requested object has not yet been loaded by the session, the object is loaded using SELECT ... FOR UPDATE. If you call load () for an object that is already loaded with a less strict lock than the one you requested, Hibernate will call lock () for that object.
Session.lock () checks the version number in READ, UPGRADE, or UPGRADE_NOWAIT modes. In the cases of UPGRADE or UPGRADE_NOWAIT, the SELECT ... FOR UPDATE syntax will be used.
If the requested lock mode is not supported by the database, Hibernate will use the appropriate alternate mode instead of throwing an exception. This ensures application portability.

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


All Articles