使用乐观锁在表中加一个version的字段来解决并发性问题
悲观锁:就是多个人同时想修改某个数据,
第一个人读出数据,数据库就锁定了其他人对该数据的修改和删除,
但允许其它人查询该数据,直到第一个人提交保存后其它人才能修改,
否则其它人在提交时系统会一直等待第一个人完成提交
乐观锁:乐观锁需要在表中加一version(版本)字段,并要在对应的类中配置
就是多个人同时想修改某个数据,如果多人同时读出数据,那么他们的版本号都相同比如是1,
然后其中有一个人最先提交了修改,那么表中版本字段会自动加一,
当其它人提交时hibernat会自动判断自己的版本号是否与数据库中的版本号相同,
如果低于数据库中的版本号那么就不允许提交。
(如果是使用jdbc开发那么用户也要自己写个判断代码进行对版本号的判断)
采用hibernate_session代码测试:
一级缓存(用hibernate_one-to-many代码测试)
1、一级缓存很短,和session的生命周期一致,随着session的关闭而消失
*load/get/iterate(查询实体对象)可以使用缓存数据
2、一级缓存它缓存的是实体对象
3、如果管理缓存,如session.clear()/session.evict()
4、如何避免一次性大批量实体数据插入内存溢出的问题?
*先执行flush,在用clear清除缓存
//发出两次load()第一次发一条sql第二次不发,说明它是先在一级缓存找数据,如果没有再到数据库找。
/**
* 发出两次load查询
*
*/
Student student = (Student)session.load(Student.class, 1);
System.out.println("学生姓名:" + student.getName());
//因为有一级缓存,load方法使用一级缓存,所以本次查询不再发出sql
student = (Student)session.load(Student.class, 1);
System.out.println("学生姓名:" + student.getName());
-------------------------------------------------------------------------------------------
//发出两次get() 同上
/**
* 发出两次get查询
*
*/
Student student = (Student)session.get(Student.class, 1);
System.out.println("学生姓名:" + student.getName());
//因为有一级缓存,get方法使用一级缓存,所以本次查询不再发出sql
student = (Student)session.get(Student.class, 1);
System.out.println("学生姓名:" + student.getName());
--------------------------------------------------------------------------------------------
/**
* 发出两次iterate查询实体对象
*
*/
public void testCache3() {
Session session = null;
try {
session = HibernateUtils.getSession();
Student student = (Student)session.createQuery("from Student where id=1").iterate().next();
System.out.println("学生姓名:" + student.getName());
//因为有一级缓存,iterate方法使用一级缓存,发出查询id的sql,不再发出查询实体对象的sql
student = (Student)session.createQuery("from Student where id=1").iterate().next();
System.out.println("学生姓名:" + student.getName());
//发出两次iterate查询实体对象
(iterate 会有n+1问题,如果缓存有发查id那1条)
先从数据库查出所有id,再根据ID查数据,所以会有n+1问题,但查实体对象会先在一级缓存查找