Skip to main content

Hibernate Locking

Locking refers to actions taken to prevent data in a relational database from changing between the time it is read and the time that it is used.

Your locking strategy can be either optimistic or pessimistic.


Locking strategies
Optimistic
Optimistic locking assumes that multiple transactions can complete without affecting each other, and that therefore transactions can proceed without locking the data resources that they affect. Before committing, each transaction verifies that no other transaction has modified its data. If the check reveals conflicting modifications, the committing transaction rolls back[1].
Pessimistic
Pessimistic locking assumes that concurrent transactions will conflict with each other, and requires resources to be locked after they are read and only unlocked after the application has finished using the data.
Hibernate provides mechanisms for implementing both types of locking in your applications.

Optimistic

When your application uses long transactions or conversations that span several database transactions, you can store versioning data, so that if the same entity is updated by two conversations, the last to commit changes is informed of the conflict, and does not override the other conversation's work. This approach guarantees some isolation, but scales well and works particularly well in Read-Often Write-Sometimes situations.
Hibernate provides two different mechanisms for storing versioning information, a dedicated version number or a timestamp.
Version number
Timestamp

A version or timestamp property can never be null for a detached instance. Hibernate detects any instance with a null version or timestamp as transient, regardless of other unsaved-value strategies that you specify. Declaring a nullable version or timestamp property is an easy way to avoid problems with transitive reattachment in Hibernate, especially useful if you use assigned identifiers or composite keys.

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


The version column can be any kind of type, as long as you define and implement the appropriateUserVersionType.
Your application is forbidden from altering the version number set by Hibernate. To artificially increase the version number, see the documentation for properties LockModeType.OPTIMISTIC_FORCE_INCREMENT orLockModeType.PESSIMISTIC_FORCE_INCREMENTcheck in the Hibernate Entity Manager reference documentation.

If the version number is generated by the database, such as a trigger, use the annotation@org.hibernate.annotations.Generated(GenerationTime.ALWAYS).

Hibernate can retrieve the timestamp value from the database or the JVM, by reading the value you specify for the @org.hibernate.annotations.Source annotation. The value can be either org.hibernate.annotations.SourceType.DBor org.hibernate.annotations.SourceType.VM. The default behavior is to use the database, and is also used if you don't specify the annotation at all.
The timestamp can also be generated by the database instead of Hibernate, if you use the@org.hibernate.annotations.Generated(GenerationTime.ALWAYS) annotation.



LockMode.WRITE
acquired automatically when Hibernate updates or inserts a row.
LockMode.UPGRADE
acquired upon explicit user request using SELECT ... FOR UPDATE on databases which support that syntax.
LockMode.UPGRADE_NOWAIT
acquired upon explicit user request using a SELECT ... FOR UPDATE NOWAIT in Oracle.
LockMode.READ
acquired automatically when Hibernate reads data under Repeatable Read orSerializable isolation level. It can be re-acquired by explicit user request.
LockMode.NONE
The absence of a lock. All objects switch to this lock mode at the end of a Transaction. Objects associated with the session via a call to update() orsaveOrUpdate() also start out in this lock mode.

Comments

Popular posts from this blog

Some good links

https://www.html5rocks.com/en/tutorials/internals/howbrowserswork/ http://taligarsiel.com/ClientSidePerformance.html -- Client side performance tips https://ariya.io/ https://vertx.io/docs/ -- New exciting Framework, Must read. https://javaee.github.io/ -- Very good resource to see various javaee projects and explore enterprise architecture and design concepts. https://projects.eclipse.org/projects/ee4j -- Lots of interesting open source projects by eclipse http://openjdk.java.net/projects/mlvm/ -- the main project for supporting more dynamic languages to jvm. http://esprima.org/ -- EcmaScript parser http://c2.com/ppr/ and http://hillside.net/ -- Good place to learn patterns http://cr.openjdk.java.net/~briangoetz/lambda/Defender%20Methods%20v4.pdf https://validator.w3.org/nu/ -- This will validate your website css and js https://www.cellstream.com/intranet/reference-reading/faq/216-what-is-2-128.html http://shattered.io/ -- An example of SHA1 collision attack.

@MappedSuperclass vs. @Inheritance

MappedSuperClass must be used to inherit properties, associations, and methods. Entity inheritance must be used when you have an entity, and several sub-entities. You can tell if you need one or the other by answering this questions: is there some other entity in the model which could have an association with the base class? If yes, then the base class is in fact an entity, and you should use entity inheritance. If no, then the base class is in fact a class that contains attributes and methods that are common to several unrelated entities, and you should use a mapped superclass. For example: You can have several kinds of messages: SMS messages, email messages, or phone messages. And a person has a list of messages. You can also have a reminder linked to a message, regardless of the kind of message. In this case, Message is clearly an entity, and entity inheritance must be used. All your domain objects could have a creation date, modification date and ID, and you could thus

Hashmap Keyset and EntrySet difference.

If you're concerned about performance when iterating through your hash map, I suggest you have a look at  LinkedHashMap . From the docs: Iteration over the collection-views of a LinkedHashMap requires time proportional to the size of the map, regardless of its capacity. Iteration over a HashMap is likely to be more expensive, requiring time proportional to its capacity. HashMap.entrySet() The source-code for this implementation is available. The implementation basically just returns a new  HashMap.EntrySet . A class which looks like this: private final class EntrySet extends AbstractSet < Map . Entry < K , V >> { public Iterator < Map . Entry < K , V >> iterator () { return newEntryIterator (); // returns a HashIterator... } // ... } and a  HashIterator  looks like private abstract class HashIterator < E > implements Iterator < E > { Entry < K , V > next ; // next entry to ret