hibernate中的事务
Hibernate中的事务:
在数据库操作中,一项事务是由一条或多条操作数据库的SQ语句组成的一个不可分割的工作单元。当事务中的所有操作都正常完成时,整个事务才能被提交到数据库中,如果由一项操作没有完成,则整个事务都会被回滚。
事务的四个特性acid:
a:原子性------事务中包含的一系列操作,要完成一起完成,要么全不执行
c:一致性-------事务完成时,所有的数据要保持一致的状态。比如tom和jerry每人各有1000元,tom给jerry转了100,这时jerry有1100,tom有900,数据的总量在事务提交前后是一致的。
i:隔离性------一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能相互干扰。
d:持久性--------指的是一个事务一旦提交,它对数据库中数据的改变是永久性的,提交后的其他操作或故障不会对其有任何影响。
事务并发问题
- 脏读====读到了某个事务还未提交的数据。
- 不可重复读====一个事务读到了另一个事务已经提交的数据,该事务可能还会回滚,导致同一个事务中的多次查询结果不一致。
- 幻读|虚读====一个事务读到了另一个事务已经提交的insert的数据,导致在同一个事务中多次查询结果不一致。例如一个事务删除某个表中的数据,而另一个事务向该表中添加数据,第一个事务删除数据之后查询发现又有新数据产生。
事务的隔离级别
为了避免事务并发问题的产生,在标准SQL规范中,定义额4个事务隔离级别,不同的隔离级别对事务的处理不同。
- 1读未提交:一个事务在执行过程中,可以读取其他事务未提交的数据。如果一个事务已经开始写数据,则另外一个事务不允许同时进行写操作,但允许其他事务读此行数据。
- 2读已提交:一个事务在执行过程中,可以读取其他事务已经提交的数据,可以有效防止脏读。
- 4可重复读:一个事务在执行过程中,可以访问其他事务成功提交的新插入的数据,但是不可以访问其他事务成功修改的事务。读取数据的事务将会禁止写事务但是允许读事务,写事务则禁止任何其他事务。此隔离级别可有效的防止不可重复读和脏读。
- 8序列化/串行化:提供严格的事务隔离,它要求事务序列化执行,不能并发执行。可以有效的防止脏读、不可重复读和幻读。
事务的隔离级别是由数据库提供的,并不是所有的数据库都支持四种隔离级别:
MySQL:READ_UNCOMMITTED READ_COMMITTED REPEATABLE_READ SEROALIZABLE(默认是REPEATABLE_READ)
ORACLAE:READ_UNCOMMITTED READ_COMMITTED SEROALIZABLE(默认是READ_COMMITTED)
在使用数据库的时候,隔离级别越高,安全性越高,性能越低,在实际开发中不会选择最高或最低隔离级别,选择READ_COMMITTED或REPEATABLE_READ。
在主配置文件hibernate.cfg.xm文件中使用
hibernate.cfg.xml
<!--1.读未提交,2.读已提交,4.可重复读,8.序列化-->
<property name="hibernate.connection.isolation">4</property>
在项目中如何管理事务:在service层进行事务管理,在业务开始之前打开事务session.beginTransaction(),在业务执行之后提交事务transaction.commit(),执行过程中出现异常则回滚事务。
那么问题来了:在DAO层操作数据库需要用到session对象session.save() session.update(),在service层控制事务也需要用到session对象,所以要确保service层和Dao层使用同一个session对象.
使用hibernate时,调用sessionFactory.getCurrentSession()即可。
注意:调用sessionFactory.getCurrentSession()需要配合主配置文件中的如下配置:
hibernate.cfg.xml
<!--指定session与当前线程绑定-->
<peoperty name="hibernate.current_session_context_class">thread</property>
注意:当通过getCurrentSession方法获得的session对象,当事务提交时,session会自动关闭,切记不要手动调用close()关闭,否则会报异常session already close。

浙公网安备 33010602011771号