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 = 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(串行化):可避免脏读、不可重复读、虚读情况的发生。

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

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

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

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

脏读 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不允许不允许不允许 不允许 不允许

转载于:https://www.cnblogs.com/lukelook/p/10743823.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值