日期:2014-05-16  浏览次数:20494 次

session.flush() 数据库的隔离级别

session flush 测试:

?

session flush 主要做了两件事:

1.清理缓存;

2.执行sql;

?

session在什么情况下执行flush

1.默认在事务提交时;

2.显示的调用flush;

3.在执行查询前,如:iterate 迭代器

?

插入一条语句,

测试uuid主键生成策略:

?

uuid的主键生成策略,是hibernate提供的,调用了save方法后,虽然不会发出sql语句,session中exitsInDatabase状态为false,执行了session.flush后,如果此时数据库的隔离级别设置为提角度,那么我们可以看到flush过的数据,并且session中exitsInDatabase的状态为true。

提交事务,默认情况下commit操作会先执行flush清理缓存,所以不用显式的调用flush,commit后数据无法回滚。

?

插入一条语句,

测试native主键生成策略:

?

user的主键生成策略为native,所以调用session.save后,将执行insert语句?,采用native的主键生成策略,id号是数据库生成的,所以save后,为保证有id生成所以该条数据已经保存到了数据库中,数据的状态已经是persistence,纳入了session的管理,如果数据库的隔离级别是未提交读,那么我们可以看见save的数据。

这里不用手动falsh就能看见save后的数据的主要原因还是uuid主键是hibernate生成的,而native主键策略是数据库负责的。

?

?

锁:具有排它性。

?

悲观锁(pessimitic lock):通常依赖于数据库机制,在整个过程中将数据锁定,其他任何数据都不能读取或者修改。

使用的时候,eg:session.load(entityName, id, lockMode);

乐观锁:其实不是锁,是一种冲突解决手段,并发性好。

?

乐观锁数在据库中的表都设置一个版本号,在数据库中设置一个version字段,该字段不许要我们维护,交给hibernate。假设用户A,B都在同一时间取了相同的数据(版本号一样),A修改了数据后,版本号就+1,存回了数据库,B在A提交之后,也把自己修改的想提交给数据库,这时候数据库比较版本号,发现B的版本号比较低,就存不进去,旧数据(版本号 <= 新数据)是不能更新新数据的,出现了更新丢失(lost update)的问题。hibernate会报出提交的是条脏数据的错误。

有的乐观锁实现方式是用了时间戳,根据时间判断版本新旧,但不如比较版本号用的多。

?

数据库中加入version字段,在实体类中加入private int version属性,在该实体的映射文件的class标签下用

optimistic-lock="version" ,表明该实体是受乐观锁根据版本号version控制,并在class表现下加入<property

name = "version"/>

?

数据库的隔离级别:

?

未提交读:数据没有提交就能在数据库中读到数据(基本没有数据库采用)。

已提交读:数据提交后才能在数据库中读到(oracle默认)。

可重复读:同一查询在同一事务中多次进行,其他提交事务不能对该事物操作的对象修改或删除,相当于悲观锁,所以不管对该事务读取多少次,都是一样的结果(mysql默认)。
?

?

在事务提交之时候,session·.flush()会被首先执行,hibernate用它清理缓存,执行sql。

什么时候需要对hibernate的session进行flush和clear

?http://www.iteye.com/wiki/topic/838089