默认事务之间会产生数据冲突,所以要求事务在读取数据的时候就对数据加锁,保证数据访问的排它性;
该锁将一直被事务持有,直到事务结束才会释放锁。
一、悲观锁
最常用的,是对查询进行加锁(LockMode.UPGRADE和LockMode.UPGRADE_NOWAIT),悲观锁的可以通过以下三种方式实现:
1)调用Session.load(),并设置了LockMode
2)调用Session.lock()
3)调用Query.setLockMode()
package edu.test;
import org.hibernate.LockMode;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import edu.po.Users;
import edu.utils.HibernateSessionFactory;
/**
* Title: PessimisticLockTest.java
* Description: 悲观锁测试
* @author yh.zeng
* @date 2017-6-27
*/
public class PessimisticLockTest {
static SessionFactory sessionFactory = HibernateSessionFactory.getSessionFactory();
public static void main(String args[]){
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
try {
//方式一,使用Session.load()给数据加悲观锁
Users user = (Users) session.load(Users.class, 6, LockMode.UPGRADE);
System.out.println("用户名:" + user.getUsername() + ",密码:" + user.getPassword());
/*
* //方式二,使用Session.lock()给对象加悲观锁
Users user = (Users) session.load(Users.class, 6);
session.lock(user, LockMode.UPGRADE);
*/
/*
* //方式三,使用Query.setLockMode()给数据加悲观锁
* String hql = "from Users u where u.id = :id";
Query query = session.createQuery(hql);
query.setParameter("id", 6);
query.setLockMode("u", LockMode.UPGRADE);
List<Users> userList = query.list();
for(Users user : userList){
System.out.println("用户名:" + user.getUsername() + ",密码:" + user.getPassword());
}*/
transaction.commit();
} catch (Exception e) {
e.printStackTrace();
transaction.rollback();
}finally{
session.close();
}
}
}
hibernate会在生成的SQL后面加上for update子句:
Hibernate: select users0_.id as id0_0_, users0_.version as version0_0_, users0_.username as username0_0_, users0_.password as password0_0_ from