Why Locking is required?
When two concurrent users try to update database row simultaneously, there are absolute chances of losing data integrity. Locking comes in picture to avoid simultaneous updates and ensure data integrity.

Types of Locking
There are two types of locking, Optimistic and Pessimistic. In this post optimistic locking is described with example.
  • Optimistic Locking: This locking is applied on transaction commit. If entity (database row) is fetched by two users simultaneously, where first user updates and commits the row and second user tries to update row with an old version. Second user will get an exception as row is already updated and version is changed. A version number is associated for entity object to achieve optimistic locking. Whenever entity object is changed, its version number is automatically increased by one. If any transaction is performed on older version of entity, transaction is failed and application throws optimistic locking exception.
  • Pessimistic Locking: Pessimistic locking explicitly restricts shared resources until the transaction completed. To get more detail about pessimistic locking refer this link .  

How to Implement Optimistic Locking in JPA 2.0?
Let’s take an example; there are two Tables Company and Employee:

Table: Company
Company_Id
Company_Name
Address
Survey_Sequnce
Version
1
AirTel
xyz
110
20
2
Reliance
abc
230
40

Table: Employee
Employee_Id
Employee_Name
Company_Id
Employee_Survey_No
1
Narendra
1
111
2
Vinay
1
112
3
Ranu
2
231
4
Rinku
2
232

Whenever, employee joins the company, he is asked to complete the company specific survey and after completion of the survey, 'Employee_Survey_No' is generated based on SURVEY_SEQUENCE from company table. To generate the survey number below steps are performed:
  1.     Read the current sequence value specific to a company from company table   (SURVEY_SEQUENCE)
  2.       Increment the sequence count by 1
  3.       Update the incremented value in company table (SURVEY_SEQUENCE)
  4.       Use this incremented value to log into employee table as 'Employee_Survey_No'
In this use case, there are absolute chances that two parallel surveys are performed for same company, where two employees get same survey sequence. This scenario can be handled with the help of optimistic locking in JPA to avoid sequence update collisions for same company.
Let’s implement optimistic locking in JPA. JPA facilitates easy approach to handle optimistic locking.
Define the company entity and annotate version column property with @Version to enable optimistic locking for entity.
@Entity
@Table(name = "Company", schema = "MyDB")
public class Company {
    private Long companyId;
    private String companyName;
    private String address;
    private Long surveySequence;
    private Long version;
   
    @Id
    @SequenceGenerator(name = "company_seq", sequenceName = "MyDB.company_seq")
    @GeneratedValue(generator = "company_seq")
    @Column(name = "COMPANY_ID", unique = true, nullable = false)
    public Long getCompanyId() {   
        return companyId;
    }   
    public void setCompanyId(Long companyId) {   
        this.companyId = companyId;
    }   
    @Column(name = "COMPANY_NAME")
    public String getCompanyName() {   
        return companyName;
    }   
    public void setCompanyName(String companyName) {   
        this.companyName = companyName;
    }   
    @Column(name = "ADDRESS")
    public String getAddress() {
        return address;
    }   
    public void setAddress(String address) {   
        this.address = address;
    }   
    @Column(name = "SURVEY_SEQUENCE")
    public Long getSurveySequence() {   
        return surveySequence;
    }   
    public void setSurveySequence(Long surveySequence) {   
        this.surveySequence = surveySequence;
    }   
    @Column(name = "VERSION_ID")
    @Version
    public Long getVersion() {   
        return version;
    }   
    public void setVersion(Long version) {   
        this.version = version;
    }  
   
}

Now create the company DAO method to fetch the survey sequence, increment and update incremented value into company table. As we have annotated company table column with @Version, JPA will take care about parallel company entity updates. If any transaction is performed with older version of entity, transaction is failed and this method will throw ‘OptimisticLockingFailureException’.

@Repository("companyDAO")
public class CompanyDAO {

    public Long getNextSurveySequence(Long companyId) {
      
        //Fetch company entity based on companyId
        Company company = entityManager.findById(Company.class, companyId);
      
        // Get the current survey sequence
        Long surveySeq = company.getSurveySequence();
      
        // Increment current sequence by 1
        Long nextSurveySeq = surveySeq + 1L;

        // Set new sequence in company entity
        Company.setSurveySequence(nextSurveySeq)
       
        // Update company with new sequence
        entityManager.merge(company);

        return nextSurveySeq;
  }
}

Now create the service method to fetch the next survey sequence and handle optimistic locking exception. With maximum try count approach, you can retry data base operation for failed transactions.

@Service("companyService")
public class CompanyService {

   public Long getNextSequenceForOrgId(Long companyId) throws Exception {
   
    Long surveySequence = null;

   //If any transaction is performed on older version of entity,
   //transaction is failed and application throws the ‘OptimisticLockException’

    for (int maxTryCount = 1; maxTryCount <= 3; maxTryCount++)
    {
       try {
             surveySequence = companyDao.getNextSurveySequence(companyId);

             break;

       } catch (OptimisticLockingFailureException e) {
           
           if (maxTryCount == 3) {                       
                throw new Exception(e);
            }
       }
     }
    return surveySequence;
   }
}

I hope this post helps you understanding and implementing optimistic locking with JPA. If you would like to share your thoughts on it, you are most welcome to comment.
0

Add a comment

You might be seeking for the option to profile (capturing method's execution time) your spring application. Spring provides different ways to profile the application. Profiling should be treated as a separate concern and spring AOP facilitates easy approach to separate this concern. With the help of spring AOP you can profile your methods without making any changes in actual classes. 

You just need to perform pretty simple steps to configure your application for profiling using spring AOP:

In application context file, add below tag to enable the load time weaving          context:load-time-weaver      

With this configuration, AspectJ's Load-time weaver is registered with current class loader.

Why Locking is required?

When two concurrent users try to update database row simultaneously, there are absolute chances of losing data integrity. Locking comes in picture to avoid simultaneous updates and ensure data integrity.

Types of Locking

There are two types of locking, Optimistic and Pessimistic. In this post optimistic locking is described with example.

Optimistic Locking: This locking is applied on transaction commit.

I have got a problem in coding contest. In this post, I would like to share the approach to solve this problem. I would definitely not say that I have invented something new and I am not trying to reinvent the wheel again. I just described the end to end approach that I followed to solve this problem.It was really a great brain storming activity.

Jenkins is an open source tool which provides continuous integration services for software development. If you want to get more detail about Jenkins and it's history I would suggest refer this link. This post will help you installing and configuring Jenkins and creating jobs to trigger maven builds. Setting up Jenkins is not a rocket science indeed. In this post, I would like to concise the installation and configuration steps.

Peer code review is an important activity to find and fix mistakes which are overlooked during development. It helps improving both software quality as well as developers skills. Though, it’s a good process for quality improvement. But this process becomes tedious if you need to share files and send review comments through mails, you need to organize formal meetings and you need to communicate peers who are in different time zone.

If you are using Hudson as continuous integration server and you might feel lazy about accessing Hudson explicitly to check the build status or checking Hudson build status mails, there is an option to monitor Hudson build and perform build activities in Eclipse IDE itself. This post describes about installing, configuring and using the Hudson in Eclipse IDE.

As a developer or architect, you always need to draw some sequence diagrams to demonstrate or document your functionality. And of course, if you do this manually you have to spare much time for this activity. Just think about, what If sequence diagram is generated automatically and you get it free of cost. Your reaction would be ‘wow’ this is great. But the next question will be ‘how’.

If you are using JPA 2.0 with Hibernate and you want to do audit logging from middle-ware itself, I believe you landed up on the exact place where you should be. You can try audit logging in your local environment by following this post.

Required JPA/Hibernate Maven Dependencies

JPA Configuration in Spring Application Context File

For JPA/Hibernate, you need to configure entity manager, transaction, data source and JPA vendor in your ‘applicationContext.xml’ file.

If any issue is observed in production, there are two major aspects related to providing the solution. First ‘how quick you can analyze the root cause’ and second ‘how quick you can fix the issue’. Story starts from analyzing the root cause. Unless, you find the root cause, you can’t even think about providing solution for that. Can you?

Now let’s think about actual production environment. There may be multiple JVMs where application is deployed.
Loading