Java软件开发基础知识梳理之(8)------Hibernate并发控制

来源:互联网 发布:儿童编程在线教育 编辑:程序博客网 时间:2024/05/21 06:45

一、悲观锁(Pessimistic Lock)
悲观锁是Hibernate基于数据库的机制来实现的,根据是否设定了查询条件可以锁定指定的记录或锁定整个表
1 可选的锁定模式有如下几种:
LockOptions.NO_WAIT:
LockOptions.NONE:
LockOptions.READ:
LockOptions.UPGRADE:会在生成的sql语句最后加上"for update"
LockOptions.WAIT_FOREVER:
2 用于设定LockMode的接口
query.setLockMode(String alias, LockMode lockMode)
query.setLockOptions(LockOptions lockOptions)
session.get(....)
session.load(....)
session.resh(....)
criteria.setLockMode(LockMode lockMode)
二、乐观锁
hibernate基于数据版本(Version)记录机制实现,为数据增加一个版本标识,严格来讲,乐观锁是一种冲突检测机制
1 实体映射时采用@Version字段标识版本号,可以是整型也可以是Timestamp,如下所示
@javax.persistence.Entity
@Table(name = "t_concurrency_user")
public class User {
 @Id
 @GeneratedValue(strategy = GenerationType.AUTO)
 private Integer id;
 @Column
 private String name;
 @Column
 private String sex;
 @Version
 private int version;
 ....
2 提交更新时,如果版本号大于数据表当前版本号,刚更新成功,否则认为是脏数据,抛出org.hibernate.StaleObjectStateException异常
三、乐观锁机制由Hibernate提供保证,悲观锁则是借助于数据库层提供的锁机制来实现

四、实例代码

1 悲观锁实体类

package com.justin.hibernate.model.currencycontrol;import javax.persistence.Column;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.Table;import javax.persistence.Version;/** *  * Author: Justin Hu * Create Date: Apr 16, 2014 * Description:  * */@javax.persistence.Entity@Table(name = "t_concurrency_user")public class User {@Id@GeneratedValue(strategy = GenerationType.AUTO)private Integer id;@Columnprivate String name;@Columnprivate String sex;@Versionprivate int version;//Getter and setter methodspublic Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public int getVersion() {return version;}public void setVersion(int version) {this.version = version;}}

2 乐观锁实体类

package com.justin.hibernate.model.currencycontrol;import javax.persistence.Column;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.Table;import javax.persistence.Version;/** *  * Author: Justin Hu * Create Date: Apr 16, 2014 * Description:  * */@javax.persistence.Entity@Table(name = "t_concurrency_person")public class Person {@Id@GeneratedValue(strategy = GenerationType.AUTO)private Integer id;@Columnprivate String name;@Columnprivate String sex;//Getter and setter methodspublic Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}}


3 HibernatePessimisticControlTest.java

package com.justin.hibernate.currencycontrol;import java.util.List;import java.util.Random;import org.hibernate.Criteria;import org.hibernate.LockOptions;import org.hibernate.Query;import org.hibernate.Session;import org.hibernate.Transaction;import org.hibernate.criterion.Restrictions;import org.testng.annotations.Test;import com.justin.hibernate.HibernateSessionFactory;import com.justin.hibernate.model.currencycontrol.Person;/** *  * Author: Justin Hu * Create Date: Apr 17, 2014 * Description:  * */public class HibernatePessimisticControlTest {@Testpublic void createEntity() {Random random = new Random();Session session = HibernateSessionFactory.getSession();Transaction tx = session.beginTransaction();Person person = new Person();int seqNum = random.nextInt(100);person.setName("Justin_" + seqNum);if (seqNum % 2 == 0) {person.setSex("Male");} else {person.setSex("Female");}session.save(person);tx.commit();session.close();}@Test@SuppressWarnings({ "unused", "unchecked" })public void queryWithLockOptionNone() {Session session = HibernateSessionFactory.getSession();Transaction tx = session.beginTransaction();String hql = "from Person as m where id = 1";Query query = session.createQuery(hql);query.setLockOptions(LockOptions.NONE);List<Person> personList = query.list();tx.commit();session.close();}@Test@SuppressWarnings({ "unused", "unchecked" })public void queryWithLockOptionRead() {Session session = HibernateSessionFactory.getSession();Transaction tx = session.beginTransaction();String hql = "from Person as m where id = 1";Query query = session.createQuery(hql);query.setLockOptions(LockOptions.READ);List<Person> personList = query.list();tx.commit();session.close();}@Test@SuppressWarnings({ "unused", "unchecked" })public void queryWithLockOptionUpgrade() {Session session = HibernateSessionFactory.getSession();Transaction tx = session.beginTransaction();String hql = "from Person as m where id = 1";Query query = session.createQuery(hql);query.setLockOptions(LockOptions.UPGRADE);List<Person> personList = query.list();tx.commit();session.close();}@Test(invocationCount = 2, threadPoolSize = 2)@SuppressWarnings({ "unused", "unchecked" })public void queryWithLockOptionUpgradeInMultiThread() {Session session = HibernateSessionFactory.getSession();Transaction tx = session.beginTransaction();String hql = "from Person as m where id = 1";Query query = session.createQuery(hql);query.setLockOptions(LockOptions.UPGRADE);List<Person> personList = query.list();tx.commit();session.close();}@SuppressWarnings({ "unchecked" })@Test(invocationCount = 2, threadPoolSize = 2)public void modifyWithLockOptionUpgradeInMultiThread() {try {Session session = HibernateSessionFactory.getSession();Transaction tx = session.beginTransaction();tx.setTimeout(60);Criteria criteria = session.createCriteria(Person.class);criteria.setLockMode(LockOptions.UPGRADE.getLockMode());criteria.add(Restrictions.eq("sex", "Male"));List<Person> personList = criteria.list();if(personList != null && !personList.isEmpty()){Person person = (Person) personList.get(0);person.setName(person.getName() + "_new");}tx.commit();session.close();System.out.println("**************");} catch (Exception e) {e.printStackTrace();}}}

4  HibernateOptimisticControlTest.java

package com.justin.hibernate.currencycontrol;import java.util.List;import java.util.Random;import org.hibernate.Criteria;import org.hibernate.Session;import org.hibernate.Transaction;import org.hibernate.criterion.Restrictions;import org.testng.annotations.Test;import com.justin.hibernate.HibernateSessionFactory;import com.justin.hibernate.model.currencycontrol.User;/** *  * Author: Justin Hu * Create Date: Apr 17, 2014 * Description:  * */public class HibernateOptimisticControlTest {@Testpublic void createEntity(){Random random = new Random();Session session = HibernateSessionFactory.getSession();Transaction tx = session.beginTransaction();User user = new User();int seqNum = random.nextInt(100);user.setName("Justin_" + seqNum);if(seqNum % 2 == 0){user.setSex("Male");}else{user.setSex("Female");}session.save(user);tx.commit();session.close();}@SuppressWarnings({"unchecked" })@Testpublic void modifyEntityInSingleTx(){Session session = HibernateSessionFactory.getSession();Transaction tx = session.beginTransaction();Criteria criteria = session.createCriteria(User.class);criteria.add(Restrictions.eq("sex", "Male"));List<User> userList = criteria.list();User user = (User) userList.get(0);user.setName(user.getName() + "_new");tx.commit();session.close();System.out.println("*******************");}@SuppressWarnings("unchecked")@Test(invocationCount = 2, threadPoolSize = 2)public void modifyEntityInMultiThread() {try {Session session = HibernateSessionFactory.getSession();Transaction tx = session.beginTransaction();Criteria criteria = session.createCriteria(User.class);criteria.add(Restrictions.eq("sex", "Male"));List<User> userList = criteria.list();User user = (User) userList.get(0);user.setName(user.getName() + "_new");tx.commit();session.close();} catch (Exception e) {e.printStackTrace();}}}


0 0
原创粉丝点击