Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 531009
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 13, 20262026-05-13T09:15:23+00:00 2026-05-13T09:15:23+00:00

I have a servlet that does some work for user and then decrement user’s

  • 0

I have a servlet that does some work for user and then decrement user’s credit. When I watch user’s credit in the database in real time, if there are many concurrent requests from the same user, the credit has been deducted incorrectly due to concurrency control. T
Assume I have one server and database management used is hibernate.
I am using transaction control to span the whole request, please see code for detail. I have several questions:

  1. Why are the credit counter in db jumping all over the place when facing many concurrent request from same user? why isn’t my transaction control working?

  2. If underlying data was modified after I retrieved user account and then attempt to update it, why didn’t I get any HibernateException(eg.StaleObjectException)?

  3. I have transaction span across the full user request, is there a better way? Please critique. Feel free to rewrite the sample code structure if you feel I’m doing the whole thing wrong.

Main servlet class:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

            try{
                Manager.beginTransaction();
                cmdDowork(request, response);
                Manager.commitTransaction();
            }catch(Exception exp){
                Manager.rollbackTransaction();
                exp.printStackTrace();
            }
            finally{
                Manager.closeSession();
            }
}

public void cmdDowork(){
try{
     UserAccount userAccount = lazyGetUserAccount(request.getParameter("userName"));

     doWorkForUser(userAccount);//time and resource consuming process

     if(userAccount!=null) {

    decUserAccountQuota(userAccount);

     }

}catch (HibernateException e){
    e.printStackTrace();

}
}

public static UserAccount lazyGetUserAccount(String userName) {
        UserAccount userAccount = Manager.getUserAccount(userName);
        if(userAccount == null){
            userAccount = new UserAccount(userName);
            userAccount.setReserve(DEFAULT_USER_QUOTA);
            userAccount.setBalance(DEFAULT_USER_QUOTA);
            Manager.saveUserAccount(userAccount);
        }
     return userAccount;
}
    private boolean decUserAccountQuota(UserAccount userAccount) {

        if(userAccount.getBalance() 

Edit: code I used to test optimistic locking as suggested by the answer, I am not getting a any StaleObjectException, the update were committed successfully.. Session em1=Manager.sessionFactory.openSession(); Session em2=Manager.sessionFactory.openSession();

em1.getTransaction().begin(); em2.getTransaction().begin(); UserAccount c1 = (UserAccount)em1.get( UserAccount.class, "jonathan" ); UserAccount c2 = (UserAccount)em2.get( UserAccount.class, "jonathan" ); c1.setBalance( c1.getBalance() -1 ); em1.flush(); em1.getTransaction().commit(); System.out.println("balance1 is "+c2.getBalance()); c2.setBalance( c2.getBalance() -1 ); em2.flush(); // fail em2.getTransaction().commit(); System.out.println("balance2 is "+c2.getBalance());
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-13T09:15:23+00:00Added an answer on May 13, 2026 at 9:15 am

    You have two ways to handle this situation: either with pessimist locking or with optimist locking. But you seem to use neither of both, which explain probably the incorrect behaviour.

    • With optimistic locking, Hibernate will check that the user account wasn’t altered between the time it was read and saved. A concurrent transaction may then fail and be rolled back.

    • With pessimistic locking, you lock the row when you read it and it’s unlocked only when transaction completes. This prevent a concurrent transaction to read data that would become stale.

    Refreshing the entity may read new data or not depending whether the current transaction has already been committed or not, but is not a solution neither. Because you seem to also create the user account if it doesn’t exist, you can’t apply pessimist locking so easily. I would suggest you use optimistic locking then (and use for instance a timestamp to detect concurrent modifications).

    Read this other question on SO about pessimist and optimist locking. Have also a look at hibernate chapter “transaction and concurrency” and “hibernate annotations“.

    It should be as simple as adding @Version on the corresponding field, the optimisticLockStrategy default value is VERSION (a separate column is used).

    — UPDATE —

    You can test whether it works in a test case. I’ve created a simple entity Counter with an ID, value, and version fields.

     public class Counter implements Serializable {
    
        @Id
        @GeneratedValue(strategy=GenerationType.AUTO)
        @Basic(optional = false)
        @Column(name = "ID")
        private Integer id;
    
        @Column(name = "VALUE")
        private Integer value;
    
        @Column(name = "VERSION")
        @Version
        private Integer version;
        ...
    }
    

    If you update one entity sequentially it works:

      id = insertEntity( ... );
    
      em1.getTransaction().begin();               
      Counter c1 = em1.find( Counter.class, id );                
      c1.setValue( c1.getValue() + 1 );
      em1.flush();
      em1.getTransaction().commit();
    
    
      em2.getTransaction().begin();
      Counter c2 = em2.find( Counter.class, id );
      c2.setValue( c2.getValue() + 1 );
      em2.flush(); // OK
      em2.getTransaction().commit(); 
    

    I get one entity with value=2 and version=2.

    If I simulate two concurrent updates:

    id = insertEntity( ... );
    
    em1.getTransaction().begin();
    em2.getTransaction().begin();
    
    Counter c1 = em1.find( Counter.class, id );
    Counter c2 = em2.find( Counter.class, id );
    
    c1.setValue( c1.getValue() + 1 );
    em1.flush();    
    em1.getTransaction().commit();
    
    c2.setValue( c2.getValue() + 1 );
    em2.flush(); // fail    
    em2.getTransaction().commit();
    

    then the 2nd flush fails:

    Hibernate: update COUNTER set VALUE=?, VERSION=? where ID=? and VERSION=?
    Hibernate: update COUNTER set VALUE=?, VERSION=? where ID=? and VERSION=?
    Dec 23, 2009 11:08:46 AM org.hibernate.event.def.AbstractFlushingEventListener performExecutions
    SEVERE: Could not synchronize database state with session
    org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [org.ewe.Counter#15]
            at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:1765)
    

    This is so because the actual parameters in the SQL statements are:

       update COUNTER set VALUE=1, VERSION=1 where ID=xxx and VERSION=0   
       --> 1 row updated
       update COUNTER set VALUE=1, VERSION=1 where ID=xxx and VERSION=0   
       --> 0 row updated, because version has been changed in between
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Ask A Question

Stats

  • Questions 310k
  • Answers 310k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team
    Editorial Team added an answer Use ObjectListView. This was specifically designed with the idea of… May 13, 2026 at 10:08 pm
  • Editorial Team
    Editorial Team added an answer If the cookie has been written to zzz.example.com then a… May 13, 2026 at 10:08 pm
  • Editorial Team
    Editorial Team added an answer LinFu.DynamicProxy doesn't directly expose the underlying object of a proxy.… May 13, 2026 at 10:07 pm

Related Questions

I'm looking to implement a simple web-based application. The main reason I want to
I'm implementing a manager in my web app that can be called to set
I'm attempting to create a Spring application (NOT web application) to perform some simple
I've done lots of java web development using jsps and servlets, and I have
I'm trying to use some data from a PlanPlusOnline account. They only provide a

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.