时间: 2021-07-31 作者:daque
hibernate是对jdbc的轻量级东西封装,hibernate自己是不完备transaction处置功效的,hibernate的transaction本质上是底层的jdbc transaction的封装,大概是jta transaction的封装,底下咱们精细的领会: hibernate不妨摆设为jdbctransaction大概是jtatransaction,这在于于你在hibernate.properties中的摆设: #hibernate.transaction.factory_class net.sf.hibernate.transaction.jtatransactionfactory #hibernate.transaction.factory_class net.sf.hibernate.transaction.jdbctransactionfactory 即使你什么都不摆设,默许情景下运用jdbctransaction,即使你摆设为: hibernate.transaction.factory_class net.sf.hibernate.transaction.jtatransactionfactory 将运用jtatransaction,尽管你筹备让hibernate运用jdbctransaction,仍旧jtatransaction,我的警告即是什么都不配,将让它维持默许状况,如次: #hibernate.transaction.factory_class net.sf.hibernate.transaction.jtatransactionfactory #hibernate.transaction.factory_class net.sf.hibernate.transaction.jdbctransactionfactory 在底下的领会中我会给出因为。 一、jdbc transaction 看看运用jdbc transaction的功夫咱们的代码例子: session session = sf.opensession(); transaction tx = session.begintransactioin(); ... session.flush(); tx.commit(); session.close(); 这是默许的情景,当你在代码中运用hibernate的transaction的功夫本质上即是jdbctransaction。那么jdbctransaction毕竟是什么货色呢?来看看源代码就领会了: hibernate2.0.3源代码中的类 net.sf.hibernate.transaction.jdbctransaction: public void begin() throws hibernateexception { ... if (toggleautocommit) session.connection().setautocommit(false); ... } 这是启用transaction的本领,看到 connection().setautocommit(false) 了吗?是否很熟习? 再来看 public void commit() throws hibernateexception { ... try { if ( session.getflushmode()!=flushmode.never ) session.flush(); try { session.connection().commit(); committed = true; } ... toggleautocommit(); } 这是提交本领,看到connection().commit() 了吗?底下就不必我多说了,这个类代码特殊大略易懂,经过观赏使咱们领会hibernate的transaction都在干了些什么?我此刻把用hibernate写的例子翻译成jdbc,大师就一览无余了: connection conn = ...; <--- session = sf.opensession(); conn.setautocommit(false); <--- tx = session.begintransactioin(); ... <--- ... conn.commit(); <--- tx.commit(); (对应左边的两句) conn.setautocommit(true); conn.close(); <--- session.close(); 看领会了吧,hibernate的jdbctransaction基础即是conn.commit罢了,基础毫无神奇可言,只然而在hibernate中,session翻开的功夫,就会机动conn.setautocommit(false),不像普遍的jdbc,默许都是true,以是你结果不写commit也没相关系,因为hibernate仍旧把autocommit给关掉了,以是用hibernate的功夫,你在步调中不写transaction的话,数据库基础就没有反馈。 二、jtatransaction 即使你在ejb中运用hibernate,大概筹备用jta来处置跨session的长工作,那么就须要运用jtatransaction,先看一个例子: javax.transaction.usertransaction tx = new initialcontext().lookup("javax.transaction.usertransaction"); session s1 = sf.opensession(); ... s1.flush(); s1.close(); ... session s2 = sf.opensession(); ... s2.flush(); s2.close(); tx.commit(); 这是规范的运用jta的代码片断,transaction是跨session的,它的人命周期比session要长。即使你在ejb中运用hibernate,那么是最大略然而的了,你什么transaction代码十足都不要写了,径直在ejb的安置刻画符上摆设某某本领能否运用工作就不妨了。 此刻咱们来领会一下jtatransaction的源代码, net.sf.hibernate.transaction.jtatransaction: public void begin(initialcontext context, ... ... ut = (usertransaction) context.lookup(utname); ... 看领会了吗? 和我上头写的代码 tx = new initial context?().lookup("javax.transaction.usertransaction"); 是否实足一律? public void commit() ... ... if (newtransaction) ut.commit(); ... jtatransaction的遏制略微搀杂,然而仍旧不妨很领会的看出来hibernate是怎样封装jta的transaction代码的。 然而你此刻能否看到了什么题目? 提防想一下,hibernate transaction是从session中赢得的,tx = session.begintransaction(),结果要先提交tx,而后再session.close,这实足适合jdbc的transaction的操纵程序,然而这个程序是和jta的transactioin操纵程序完全冲突的!!! jta是先启用transaction,而后启用session,封闭session,结果提交transaction,所以当你运用jta的transaction的功夫,那么就万万不要运用hibernate的transaction,而是该当像我上头的jta的代码片断那么运用才行。 归纳: 1、在jdbc上运用hibernate 必需写上hibernate transaction代码,要不数据库没有反馈。此时hibernate的transaction即是connection.commit罢了 2、在jta上运用hibernate 写jta的transaction代码,不要写hibernate的transaction代码,要不步调会报错 3、在ejb上运用hibernate 什么transactioin代码都不要写,在ejb的安置刻画符内里摆设 |---cmt(container managed transaction) | |---bmt(bean managed transaction) | |----jdbc transaction | |----jta transaction