Hibernate设置事务的隔离级别

方式有两种:面试

1)修改配置文件hibernate.cfg.xml实现数据库

<hibernate-configuration>
 
    <session-factory> ...... <!-- 事务隔离级别 0:TRANSACTION_NONE 1:TRANSACTION_READ_UNCOMMITTED 2:TRANSACTION_READ_COMMITTED 4:TRANSACTION_REPEATABLE_READ 8:TRANSACTION_SERIALIZABLE -->
        <property name="hibernate.connection.isolation">4</property> ...... </session-factory>
 
</hibernate-configuration>

2)代码方式session

Session session = sessionFactory.openSession(); session.connection().setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);

Serializable:串行化。隔离级别最高 
Repeatable Read:可重复读 
Read Committed:已提交数据读 
Read Uncommitted:未提交数据读。隔离级别最差 
设置锁:乐观锁和悲观锁。 
乐观锁:使用版本号或时间戳来检测更新丢失,在的映射中设置 optimistic-lock=”all”能够在没有版本或者时间戳属性映射的状况下实现 版本检查,此时Hibernate将比较一行记录的每一个字段的状态 行级悲观锁:Hibernate老是使用数据库的锁定机制,从不在内存中锁定对象!只要为JDBC链接指定一下隔 离级别,而后让数据库去搞定一切就够了。类LockMode 定义了Hibernate所需的不一样的锁定级别:LockMode.UPGRADE,LockMode.UPGRADE_NOWAIT,LockMode.READ;并发

隔离级别性能

Serializable(串行化):可避免脏读、不可重复读、虚读状况的发生。spa

Repeatable read(可重复读):可避免脏读、不可重复读状况的发生。hibernate

Read committed(读已提交):可避免脏读状况发生。线程

Read uncommitted(读未提交):最低级别,以上状况均没法保证。code

总结:Serializable隔离级别,虽然可避免全部问题,但性能、效率是最低的,缘由是它采起的是锁表的方式,即单线程的方式,即有一个事务来操做这个表了,另一个事务只能等在外面进不来。随着隔离级别的增高,并发性能下降,随之会引起运行的性能、效率问题

xml

脏读 dirty reads:当事务读取还未被提交的数据时,就会发生这种事件。举例来讲:Transaction 1 修改了一行数据,而后 Transaction 2 在 Transaction 1 还未提交修改操做以前读取了被修改的行。若是 Transaction 1 回滚了修改操做,那么 Transaction 2 读取的数据就能够看做是从未存在过的。


不可重复的读 non-repeatable reads:当事务两次读取同一行数据,但每次获得的数据都不同时,就会发生这种事件。举例来讲:Transaction 1 读取一行数据,而后 Transaction 2 修改或删除该行并提交修改操做。当 Transaction 1 试图从新读取该行时,它就会获得不一样的数据值(若是该行被更新)或发现该行再也不存在(若是该行被删除)。
虚读 phantom read:若是符合搜索条件的一行数据在后面的读取操做中出现,但该行数据却不属于最初的数据,就会发生这种事件。举例来讲:Transaction 1 读取知足某种搜索条件的一些行,而后 Transaction 2 插入了符合 Transaction 1 的搜索条件的一个新行。若是 Transaction 1 从新执行产生原来那些行的查询,就会获得不一样的行。

 

脏读:在一个事务中读取到另外一个事务没有提交的数据
不可重复读:在一个事务中,两次查询的结果不一致(针对的update操做)
虚读(幻读):在一个事务中,两次查询的结果不一致(针对的insert操做)
经过设置数据库的隔离级别来避免上面的问题(理解)
read uncommitted 读未提交 上面的三个问题都会出现
read committed 读已提交 能够避免脏读的发生
repeatable read 可重复读 能够避免脏读和不可重复读的发生
serializable 串行化 能够避免全部的问题

起初隔离级别为read uncommitted 读未提交;a,b两个会话,分别开启两个事务,而后a向b转了500元钱,但a未提交该事务,
此时b查看,发现多了500.而后a回滚事务,b再查看帐户,发现根本就没有多500.这即是脏读。
脏读即是能够读取到另外一个事务还没有提交的数据。
若是咱们此时将隔离级别提高为read committed 读已提交,即可避免脏读。一样b两个会话,分别开启两个事务,而后a向b转了500元钱,
但a未提交该事务,此时b查看,依旧是原钱数.
但此时,若是a 提交事务,b再去查看,发现此时多了500,对b而言,在一个事务中,两次查询的结果不一致,这即是不可重复读。
若是咱们此时将隔离级别提高为repeatable read 可重复读,能够避免脏读和不可重复读的发生。一样a 提交事务,b再去查看,发现
依旧是原钱数,b只能结束当前事务,在开启一个新事务,才能查询到数据的变化,这al便避免了不可重复读。
若是咱们设置了seriizable串行化,就至关于锁表,某一时间内只容许一个事务访问该表。

 

补充:关于事务,在面试中被问到的几率是很高的,能够问的问题也是不少的。 首先须要知道的是,只有存在并发数据访问时才须要事务。当多个事务访问同一数据时, 可能会存在5类问题,包括3类数据读取问题(脏读、不可重复读和幻读)和2类数据更新问题(第1类丢失更新和第2类丢失更新)。 第1类丢失更新:事务A撤销时,把已经提交的事务B的更新数据覆盖了。 第2类丢失更新:事务A覆盖事务B已经提交的数据,形成事务B所作的操做丢失。

隔离级别脏读不可重复读幻读第一类丢失更新第二类丢失更新

READ UNCOMMITED容许容许容许 不容许 容许

READ COMMITTED不容许容许容许 不容许 容许

REPEATABLE READ不容许不容许容许 不容许 不容许

SERIALIZABLE不容许不容许不容许 不容许 不容许

相关文章
相关标签/搜索