• 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不允许不允许不允许 不允许 不允许

  • 相关阅读:
    团队-科学计算器-成员简介及分工
    提交错误
    《结对-结对编项目作业名称-需求分析》
    对软件工程课程的期望
    自我介绍
    课堂作业0
    selenium+Java刷新浏览器
    不要焦虑~~
    JAVA代码实现得到指定文件夹下的文件名
    安全检测检查清单(IOS版APP)
  • 原文地址:https://www.cnblogs.com/lukelook/p/10743823.html
Copyright © 2020-2023  润新知