I got problem with hibernate pessimistic locking:
exp:
Code:
public class Account {
private Long id;
private String user;
private int balance;
...
}
public class AccountManager {
public static void deposit(long id){
try{
Session session = HibernateUtil.getInstance().currentSession();
Transaction tx = session.beginTransaction();
Account account = (Account)session.get(Account.class, id, LockMode.UPGRADE);
account.setBalance(account.getBalance() + 1);
System.out.println("Get balance is: " + account.getBalance());
tx.commit();
HibernateUtil.getInstance().closeSession();
}catch(Exception e){
e.printStackTrace();
}
}
}
public class UserThread extends Thread{
private final static long USER_ID = 1;
private String threadId;
public void setThreadId(String id){
threadId = id;
}
public void run(){
for(int i=0;i<100;i++){
AccountManager.deposit(USER_ID);
System.out.println("Thread: [" + threadId + "]" + "updata successfully -- " + "[" + System.currentTimeMillis() + "]" );
try{
sleep(10);
}catch(Exception e){
e.printStackTrace();
}
}
}
}
the log is like:
Code:
.......
.......
.......
Get balance is: 57
Hibernate: update account set user=?, balance=? where id=?
Thread: [Thread B ]updata successfully -- [1132931577687]
Hibernate: select account0_.id as id0_, account0_.user as user2_0_, account0_.balance as balance2_0_ from account account0_ where account0_.id=? for update
Get balance is: 58
Hibernate: update account set user=?, balance=? where id=?
Thread: [Thread B ]updata successfully -- [1132931577703]
Hibernate: select account0_.id as id0_, account0_.user as user2_0_, account0_.balance as balance2_0_ from account account0_ where account0_.id=? for update
Hibernate: select account0_.id as id0_, account0_.user as user3_0_, account0_.balance as balance3_0_ from account account0_ where account0_.id=? for update
Get balance is: 59
Get balance is: 59
Hibernate: update account set user=?, balance=? where id=?
Hibernate: update account set user=?, balance=? where id=?
Thread: [Thread A ]updata successfully -- [1132931577750]
Thread: [Thread B ]updata successfully -- [1132931577750]
Hibernate: select account0_.id as id0_, account0_.user as user3_0_, account0_.balance as balance3_0_ from account account0_ where account0_.id=? for update
Get balance is: 60
Hibernate: update account set user=?, balance=? where id=?
Thread: [Thread A ]updata successfully -- [1132931577750]
Hibernate: select account0_.id as id0_, account0_.user as user3_0_, account0_.balance as balance3_0_ from account account0_ where account0_.id=? for update
Get balance is: 61
....
....
....
I used two threads to update one account record, as described above, while both thread finish, this account balance will increase to 200. but somehow, the value increased will be less than 200, it will be 198,197. I don't know what's wrong with the pessimistic locking. Any body can tell me? Thanks.