博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hibernate的事务管理
阅读量:6566 次
发布时间:2019-06-24

本文共 3026 字,大约阅读时间需要 10 分钟。

hot3.png

在讲解hibernate的事物管理之前,我们必须首先明白一些基本的概念,以此帮助理解,为什么要事物管理这个东西,有它之后有什么用,它有哪些基本特性或者限制,

 

那么第一点,我们该知道的就是事物的4个基本特性,也就是我们常说的ACID【原子性,一致性,隔离性,持久性】;

 

第二点,应该知道的是,事物的隔离级别,即通过某种机制,在并发运行的多个事物之间进行分隔,使其保持执行时的独立性。一般分为Read Uncommitted,   Read Committed ,  Repeatable Read,  Serializable这四个隔离级别,这四种隔离级的严密程度是一次递增的,同事它的性能也是依次下降,在脏读取,不可重读,和虚读,这三个中数据库可能出现漏洞的情况下,这四个级别采取的应对措施是不同的,也就是说,这四个隔离级下,这三种情况发生的可能性是,1.可能脏读,可能重读,可能虚读;2.不可能脏读,可能重读,可能虚读; 3.不可能脏读,不可能重读,可能虚读 4.三种漏洞全都不可能发生。所以日常使用时,需根据实际情况取舍,以保持系统的最佳平衡。

 

hibernate是jdbc轻量级的封装,本身不具备事务管理的能力,在事物管理层面,一般是委托于底层的jdbc和jta来完成调度的。默认事物处理机制是基于jdbc transaction的,当然,我们也能通过配置jta来实现:

 

Xml代码 
  1. <hibernate-configuration>  
  2.     <session-factory>  
  3.         ........  
  4.             <property name="hibernate.transaction.factory_class">  
  5.                      net.sf.hibernate.transaction.JTATransactionFactory  //JTA  
  6.                     <!--net.sf.hibernate.transaction.JDBCTransactionFactory-->   //JDBC  
  7.             </property>  
  8.         ........  
  9.      </sesssion-factoty>  
  10. </hibernate-configuration>  

 

  将事物委托给jdbc处理,无疑是最简单的方式,hibernate支持它做默认方式,其事物的封装,也非常简单,比如当我们在处理这段代码时:

 

Java代码 
  1. session = sessionFactory.openSession();  
  2. Transaction tx=session.beginTransaction();  
  3. ......  
  4. tx.commit();  

 

  而从jdbc事物层面而言,实际上做的是:

 

Java代码 
  1. Connection dbconn=getConnection();  
  2. dbconn.setAutoCommit(false);  
  3. ......  
  4. dbconn.commit();  

 

  就这么简单,换了个说法,把hibernate的提交方式,在底层用原生的jdbc进行了提交,这里需要注意的是在openSession()的时候,底层的jdbc的AutoCommit属性已被关闭了,除非jdbc连接去commit,否则执行的操作将不会对数据库产生任何效果,这里那就需要我们去显示执行tx.commit()了[非事物性数据库除外,如Mysql ISam]

 

而JTA与jdbc的事物的最大差异,在于它提供了跨session的事物管理能力。jdbc事物由Connection管理,事物的周期限于Connection的生命周期。而JTA则由JTA容器实现,容器可对当前的众多Connection进行调度,于是它可横跨多个Connection生命周期,于是也提供了跨session的能力。

 

比如我们下面这段代码,在jdbc的事物下完全正确的,但是在jta下就会产生问题:

 

Java代码 
  1. class ClassA{  
  2.     public void save(User user){  
  3.          Session session=sessionFactory.openSession();  
  4.          Transaction tx=session.beginTransaction();  
  5.          session.save(user);  
  6.          tx.commit();  
  7.           
  8.         session.close();  
  9.     }  
  10. }  
Java代码 
  1. <pre class="java" name="code">class ClassB{  
  2.     public void save(Order order){  
  3.          Session session=sessionFactory.openSession();  
  4.          Transaction tx=session.beginTransaction();  
  5.          session.save(order);  
  6.          tx.commit();  
  7.           
  8.         session.close();  
  9.     }  
  10. }</pre>  
  11. class ClassC{  
  12.     public void save(){  
  13.         .....  
  14.         UserTransaction tx=(UserTranscation)(new InitialContext().lookup("...."));  
  15.          ClassA.save(user);  
Java代码 
  1.          ClassB.save(oreder);  
  2.          tx.commit();  
  3.           
  4.        ......  
  5.     }  
  6. }  

  这里的问题是,ClassA和B调用了hibernate的Transaction功能。而在hibernate的JTA分装中,Session.beginTransaction同样也执行了InitialContext.lookup去获得UserTransaction的实例,而在tx.commit的时候,ClassA和B都企图声明自己的事物,从而导致错误,因为我们知道,jdbc的事物,是不能够跨connection,跨session的。而假使使用jta,那么我们则可以修改上面代码,实现操作:

Java代码 
  1. class ClassA{  
  2.     public void save(User user){  
  3.          Session session=sessionFactory.openSession();  
  4.          session.save(user);  
  5.         session.close();  
  6.     }  
  7. }  
  8.   
  9. class ClassB{  
  10.     public void save(Order order){  
  11.          Session session=sessionFactory.openSession();  
  12.          session.save(order);  
  13.           
  14.         session.close();  
  15.     }  
  16. }  
  17.   
  18. class ClassC{  
  19.     public void save(){  
  20.      .....  
  21.          Session session=sessionFactory.openSession();  
  22.          Transaction tx=session.beginTransaction();  
  23.          ClassA.save(user);  
  24.          ClassB.save(order);  
  25.          tx.commit();  
  26.           
  27.         session.close();  
  28.     }  
  29. }  
 
在EJB中使用JTA Transaction无疑最为简单,我们只需要将save方法的属性声明为Required,Ejb容器就会自动的维护并执行过程中的事物。

 

转载于:https://my.oschina.net/bluesroot/blog/222580

你可能感兴趣的文章
js页面跳转整理
查看>>
黑客发飙!智能汽车不太安全你还敢开?
查看>>
第十四届中国计算机大会进入第二天,精彩继续 | CNCC 2017
查看>>
js基础
查看>>
为何写flash的时候要地址左移一位?
查看>>
Teradata收购Think Big Analytics 提升大数据咨询能力
查看>>
软件:向工业互联网产业成功转型的关键
查看>>
使用libFuzzer fuzz Chrome V8入门指南
查看>>
IDC:2017年,40%的CIO将失去在企业中的领导地位
查看>>
优云,新一代运维PaaS平台
查看>>
《数字逻辑设计与计算机组成》一3.3 加法器
查看>>
攀枝花市大数据中心落户东区
查看>>
《中国人工智能学会通讯》——3.15 社交媒体中的谣言识别研究及其发展趋势...
查看>>
这篇文章很好的诠释了为什么安全框架如此重要?
查看>>
《并行计算的编程模型》一2.4.1 GASNet段
查看>>
巴西C&C成为FreeStor全球首个用户
查看>>
Nutanix企业云助力广播传媒的融合媒体发展之路
查看>>
信息化道路上,这两家龙头企业做了什么
查看>>
调查显示:企业将部署SDN提上议程
查看>>
鱼缸式百分比信息图表,这样计算才正确
查看>>