美文网首页码蚁IT程序员
撩课-Java每天5道面试题第16天

撩课-Java每天5道面试题第16天

作者: 码蚁Q | 来源:发表于2018-11-16 20:17 被阅读17次

    撩课Java+系统架构点击开始学习

    什么是乐观锁(Optimistic Locking)?

    悲观锁,正如其名,
    它指的是对数据被外界
    包括本系统当前的其他事务,
    以及来自外部系统的事务处理
    修改持保守态度,
    因此,在整个数据处理过程中,
    将数据处于锁定状态。
     悲观锁的实现,
    往往依靠数据库提供的锁机制 
    也只有数据库层提供的锁机制才能真正保证数据访问的排他性,
    否则,即使在本系统中实现了加锁机制,
    也无法保证外部系统不会修改数据
    
    乐观锁( Optimistic Locking ) 
    相对悲观锁而言,
    乐观锁假设认为数据
    一般情况下不会造成冲突,
    所以在数据进行提交更新的时候,
    才会正式对数据的冲突与否进行检测,
    如果发现冲突了,
    则让返回用户错误的信息,
    让用户决定如何去做
    
    
    

    描述下Hibernate当中事务?

    一、事务的并发问题 
    在实际应用中,
    数据库是要被I多个用户共同访问的,
    在多个事务同时使用相同的数据时,
    可能会发生并发的问题,
    具体为:
    
    脏读:
    一个事务读取到
    另一个事务未提交的数据。
    
    不可重复读:
    一个事务对同一行数据
    重复读取两次,
    但是得到了不同的结果。
    
    虚读:
    一个事务连续两次在数据库进行同样条件的查询,
    但是第二次查询结果包含了
    第一次查询中未出现的数据。
    (注意与不可重复读的区别)
    
    更新丢失:
    两个事物同时更新一行数据,
    后提交(或撤销)的事务将前面事务
    提交的数据都覆盖了。 
    第一类丢失更新:
    是由于后面事务撤销将前面事务
    修改的数据覆盖了 
    第二类丢失更新:
    是由于后面事务更新将前面事务
    修改的数据覆盖了
    
    
    1、读未提交(1级,可防止更新丢失):
    当一个事务进行写(更新)数据,
    则另外一个事务不允许同时进行写(更新)数据,
    但允许其他事务进行读数据,
    即使是未提交的 (但这个不能防止脏读)
    更新丢失是因为一个事务开始进行写事务,
    另一个事务也可以进行写事务导致的。
    
    2、读已提交(2级,可防止更新丢失、脏读):
    读取数据的事务允许其他事务继续读取该数据,
    但是未提交的写事务将会禁止其他事务访问改行。
    脏读是由于读到未提及的数据
    
    3、可重复读(4级,可防止不可重复读、脏读):
    读取数据的事务禁止写事务,
    写事务将禁止其他任何事务。
    不可重复读是一个事务
    对一行数据重复读取两次,
    但是得到不同的结果;
    脏读是读到未提交的数据
    
    4、序列化(8级,防止一切并发问题):
    提供严格的事务隔离。
    事务只能一个接着一个执行,
    不能并发执行
    
    简单总结: 
    事务并发问题: 
    (1)脏读 
    (2)不可重复读 
    (3)虚读 
    (4)更新丢失 
    事务隔离级别: 
    (1)读未提交 
    (2)读已提交 
    (3)可重复读 
    (4)序列化
    
    在hibernate.cfg.xml的标签配置: 
    使用本地事务还是全局事务,参数是:
    hibernate.current_session_context_class
    值:thread(本地事务)、jta(全局事务)
    设置事务隔离级别,参数是:
    hibernate.connection.isolation
    
    当多个事务同时访问数据库中的相同数据时,
    如果没有采取必要的隔离措施,
    那么可以采用悲观锁或者是乐观锁对其进行控制。 
    悲观锁:
    悲观地认为总是会有其他事务回来操作同一数据
    因此在这个数据处理过程中,
    将会把数据处于锁定状态。
    比如读取数据时:
    User user = (User)session.get(User.class, "111111", LockMode.UPGRADE)
    
    乐观锁:
    认为事务同时操作同一个数据的情况很少发生,
    所以乐观锁不做数据库层次的锁定,
    而是基于数据版本标识
    实现应用程序级别上的锁定机制。 
    原理:数据版本标识,
    是指通过为数据表增加一个“version”字段,
    实现在读取数据时,
    将版本号一同独处,
    之后更新次数据时,
    将此版本号加一;
    在提交数据时,
    将现有的版本号
    与数据表对应的记录的版本号进行对比,
    如果提交数据的版本号大于数据表中的版本号,
    则允许更新数据,
    否则禁止更新数据。
    
    
    

    Hibernate 中的缓存分为几层。

    hibernate的缓存包括 
    Session的缓存和SessionFactory的缓存,
    其中SessionFactory的缓存又可以分为两类:
    内置缓存和外置缓存。
    Session的缓存是内置的,
    不能被卸载,
    也被称为Hibernate的第一级缓存。
    SessionFactory的内置缓存
    和Session的缓存在实现方式上比较相似,
    前者是SessionFactory对象的一些集合属性包含的数据,
    后者是指Session的一些集合属性包含的数据。
    SessionFactory的内置缓存中存放了
    映射元数据和预定义SQL语句,
    映射元数据是映射文件中数据的拷贝,
    而预定义SQL语句是
    在Hibernate初始化阶段根据
    映射元数据推导出来,
    SessionFactory的内置缓存是只读的,
    应用程序不能修改缓存中的映射元数据
    和预定义SQL语句,
    因此SessionFactory不需要进行内置缓存与映射文件的同步。
    SessionFactory的外置缓存是一个可配置的插件。
    在默认情况下,SessionFactory不会启用这个插件。
    外置缓存的数据是数据库数据的拷贝,
    外置缓存的介质可以是内存或者硬盘。
    SessionFactory的外置缓存
    也被称为Hibernate的第二级缓存
    

    Entity Beans 的状态有哪些

    瞬时(transient):
    数据库中没有数据与之对应,
    超过作用域会被JVM垃圾回收器回收,
    一般是new出来且与session没有关联的对象。
    
    持久(persistent):
    数据库中有数据与之对应,
    当前与session有关联,
    并且相关联的session没有关闭,
     事务没有提交;
    持久对象状态发生改变,
    在事务提交时会影响到数据库(hibernate能检测到)。
    
    脱管(detached):
    数据库中有数据与之对应,
    但当前没有session与之关联;
    托管对象状态发生改变,
    hibernate不能检测到。
    
    

    谈谈Hibernate中inverse的作用

    Hibernate中的inverse
    在表关系映射中经常应用
     inverse的值有两种,“true”和“false”。
    
    inverse="false"是默认的值 
    inverse的作用:
    在hibernate中是通过inverse的设置
    来决定是有谁来维护表和表之间的关系的。
    
     我们说inverse设立不当会导致性能低下,
    其实是说inverse设立不当,
    会产生多余重复的SQL语句
    甚至致使JDBC exception的throw。
    
    这是我们在建立实体类关系时
    必须需要关注的地方。
    
    一般来说,inverse=true是推荐使用,
    双向关联中双方都设置 inverse=false的话,
    必会导致双方都重复更新同一个关系。
    
    但是如果双方都设立inverse=true的话,
    双方都不维护关系的更新,
    这也是 不行的,
    好在一对多中的一端:
    many-to-one默认是inverse=false,
    避免了这种错误的产生。
    
    但是多对多就没有这个默认设置了,
    所以很 多人经常在多对多的两端都使用inverse=true,
    结果导致连接表的数据根本没有记录,
    就是因为他们双分都没有责任维护关系。
    所以说,双向关联中最 好的设置
    是一端为inverse=true,
    一端为inverse=false。
    
    一般inverse=false会放在多的一端,
    那么有人提问了, many-to-many两边都是多的,
    inverse到底放在哪儿?
    其实hibernate建立多对多关系
    也是将他们分离成两个一对多关系,
    中间连接一个连接表。
    
    所以通用存在一对多的关系,
    也可以这样说:
    一对多是多对多的基本组成部分。
    
    
    

    相关文章

      网友评论

        本文标题:撩课-Java每天5道面试题第16天

        本文链接:https://www.haomeiwen.com/subject/jmgcfqtx.html