Hibernate控制的事务
Hibernate在发送Sql把对象信息同步到数据时,不是立即进行的而是把这些要发送的Sql缓存在起来,在必要的时候发送。
通过Session的setFlushMode(FlushMode flushMode)方法,来控制在什么时候清空Sql的缓冲区,并把缓存的Sql语句发送出去。
FlushMode是一个枚举,它有3个枚举值。
FlushMode.AUTO,在持久化对象的信息被修改时,那么就要把它同步到数据库中,更新数据库中队应的记录,也就是在产生修改时就会清空缓冲区。
FlushMode.COMMIT,只有在事务提交的时候才清空缓冲区。
FlushMode.NEVER,这个值表示只有在调用了Session的flush()方法才清空缓冲区。
事务保证原子操作的不可分,也就是操作的同时成功或同时失败。
Transaction tran=session.beginTranaction();
tran.commit();
tran.rollback();
以上是事务对象的方法,来实现对事务的支持。
hibernate的事务隔离级别
hibernate的事务隔离级别和JDBC中大致相同。
设置时要在hibernate.cfg.xml配置
<property name="hibernate.connection.isolation">4</property>
1,读未提交的数据(Read uncommitted isolation)
2,读已提交的数据(Read committed isolation)
4,可重复读级别(Repeatable read isolation)
8,可串行化级别(Serializable isolation)
hibernate的锁(悲观锁,乐观锁)
悲观锁是由数据库本身所实现的,会对数据库中的数据进行锁定,也就是锁行。
LockMode.UPGRADE,修改锁,在get()方法中加上这个设置作为第三个参数。
LockMode.NONE 无锁机制
LockMode.READ 读取锁
LockMode.WRITE 写入锁,不能在程序中直接使用
还可以使用Session.lock() Query.setLockMode() Criteria.setLockMode()方法来设置锁
乐观锁,也就是通过对记录加上某些信息来解决并发访问的问题。
版本检查
要在其表中多加上一个字段表示版本信息,会在读取时读到这个版本号,并在修改之后更新这个版本号,在并发修改的时,只有数据库中记录的版本号比要更新的才进行更新操作,如果数据库记录版本号比要更新的高,就会抛出例外。
写在Xxxxx.hbm.xml中
<version name="version" column="version" type="integer" />
例:
public class User implements Serializable{
private int id;
private String name;
private String phone;
private int version;//记录版本的属性
public int getId(){
return id;
}
public void setId(int id){
this.id = id;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public String getPhone(){
return phone;
}
public void setPhone(String phone){
this.phone = phone;
}
public int getVersion(){
return version;
}
public void setVersion(int version){
this.version = version;
}
}
User类的User.hbm.xml文件
<hibernate-mapping package="alan.hbn.concur.version" auto-import="false">
<class name="User" table="user_version">
<id name="id" column="id" type="integer" unsaved-value="0">
<generator class="native"/>
</id>
<version name="version" column="version" type="integer" />
<!--版本控制,指定了版本属性的名字,和对应表中的字段和类型-->
<property name="name" column="name"/>
<property name="phone" column="phone"/>
</class>
</hibernate-mapping>