﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-细心!用心!耐心!-文章分类-事务编程</title><link>http://www.blogjava.net/jesson2005/category/19579.html</link><description>吾非文人，乃市井一俗人也，读百卷书，跨江河千里，故申城一游； 
一两滴辛酸，三四年学业，五六点粗墨，七八笔买卖，九十道人情。</description><language>zh-cn</language><lastBuildDate>Thu, 17 May 2007 03:34:15 GMT</lastBuildDate><pubDate>Thu, 17 May 2007 03:34:15 GMT</pubDate><ttl>60</ttl><item><title>Hibernate事务管理 </title><link>http://www.blogjava.net/jesson2005/articles/113524.html</link><dc:creator>张金鹏</dc:creator><author>张金鹏</author><pubDate>Wed, 25 Apr 2007 06:16:00 GMT</pubDate><guid>http://www.blogjava.net/jesson2005/articles/113524.html</guid><wfw:comment>http://www.blogjava.net/jesson2005/comments/113524.html</wfw:comment><comments>http://www.blogjava.net/jesson2005/articles/113524.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jesson2005/comments/commentRss/113524.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jesson2005/services/trackbacks/113524.html</trackback:ping><description><![CDATA[<p>Hibernate事务管理 <br>&nbsp; Hibernate是JDBC的轻量级封装，本身并不具备事务管理能力，在事务管理层，Hibernate将其委托给底层的JDBC或者JTA,以实现事务的管理和调度。</p>
<p>&nbsp; Hibernate的默认事务处理机制基于JDBCTransaction，也可以通过配置文件设定采用JTA作为事务管理实现：</p>
<p>&nbsp;&nbsp; &lt;hibernate-configuration&gt;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;session-factory&gt;</p>
<p>&nbsp;&nbsp;&nbsp; &#8230;&#8230;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;property name = "hibernate.transaction.factory_class"&gt;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; net.sf.hibernate.transaction.JTATransactionFactory</p>
<p>&nbsp;&nbsp;&nbsp; &lt;/session-factory&gt;</p>
<p>&nbsp;&nbsp; &lt;/hibernate-configuration&gt;</p>
<p>1、基于JDBC的事务管理</p>
<p>&nbsp; Hibernate对于JDBC事务的封装非常简单。例如：</p>
<p>&nbsp;&nbsp; session=sessionFactory.openSession();</p>
<p>&nbsp;&nbsp; Transaction tx= session.beginTransaction();</p>
<p>&nbsp;&nbsp; &#8230;&#8230;</p>
<p>&nbsp;&nbsp; tx.commit();</p>
<p>这里要注意的是，在sessionFactory.openSession()中，Hibernate会初始化数据库连接，与此同时，将其 AutoCommit设为关闭状态，这就是说，从SessionFactory获得session，其自动提交属性就已经被关闭了，下面的代码不会对事务性数据库产生任何效果。</p>
<p>&nbsp;&nbsp; session=sessionFactory.openSession();</p>
<p>&nbsp;&nbsp; session.save(user);</p>
<p>&nbsp;&nbsp; session.close();</p>
<p>如果要使得代码真正作用到数据库，必须显示的调用Transaction指令</p>
<p>&nbsp;&nbsp; session=sessionFactory.openSession();</p>
<p>&nbsp;&nbsp; Transaction tx = session.beginTransaction();</p>
<p>&nbsp;&nbsp; session.save(user);</p>
<p>&nbsp;&nbsp; tx.commit();</p>
<p>&nbsp;&nbsp; session.close();</p>
<p>2、基于JTA的事务管理</p>
<p>&nbsp; JTA提供了跨Session的事务管理能力，这是与JDBCTransaction最大的差异。</p>
<p>&nbsp;JDBC事务由Connection管理，也就是说，事务管理实际上是在JDBC Connection中实现，事务周期限于Connection的生命周期之内，对于基于JDBC Transaction的Hibernate事务管理机制，事务管理在Session所依托的JDBC Connection中实现，事务周期限于Session的生命周期。</p>
<p>&nbsp;&nbsp; JTA事务管理由JTA容器实现，JTA容器对当前加入事务的众多Connection进行调度，实现其事务性要求，JTA的事务周期可横跨多个JDBC Connection生命周期，同样，对基于JTA事务的Hibernate，JTA事务横跨多个Session。需要注意的是，参与JTA事务的 Connection需避免对事务管理进行干涉，如果采用JTA Transaction，就不应该再调用Hibernate的Transaction功能。<br>&nbsp;<br>&nbsp;<br></p>
<img src ="http://www.blogjava.net/jesson2005/aggbug/113524.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jesson2005/" target="_blank">张金鹏</a> 2007-04-25 14:16 <a href="http://www.blogjava.net/jesson2005/articles/113524.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JDBC Transaction与JTA Transaction的区别</title><link>http://www.blogjava.net/jesson2005/articles/113519.html</link><dc:creator>张金鹏</dc:creator><author>张金鹏</author><pubDate>Wed, 25 Apr 2007 06:11:00 GMT</pubDate><guid>http://www.blogjava.net/jesson2005/articles/113519.html</guid><wfw:comment>http://www.blogjava.net/jesson2005/comments/113519.html</wfw:comment><comments>http://www.blogjava.net/jesson2005/articles/113519.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jesson2005/comments/commentRss/113519.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jesson2005/services/trackbacks/113519.html</trackback:ping><description><![CDATA[Hibernate是对JDBC的轻量级对象封装，Hibernate本身是不具备Transaction处理功能的，Hibernate的Transaction实际上是底层的JDBC Transaction的封装，或者是JTA Transaction的封装，下面我们详细的分析： <br><br>　　Hibernate可以配置为JDBCTransaction或者是JTATransaction，这取决于你在hibernate.properties中的配置: <br><br>　　#hibernate.transaction.factory_class <br>　　net.sf.hibernate.transaction.JTATransactionFactory <br>　　#hibernate.transaction.factory_class <br>　　net.sf.hibernate.transaction.JDBCTransactionFactory <br><br>　　如果你什么都不配置，默认情况下使用JDBCTransaction，如果你配置为： <br><br>　　hibernate.transaction.factory_class <br>　　net.sf.hibernate.transaction.JTATransactionFactory <br><br>　　将使用JTATransaction，不管你准备让Hibernate使用JDBCTransaction，还是JTATransaction，我的忠告就是什么都不配，将让它保持默认状态，如下： <br><br>　　#hibernate.transaction.factory_class <br>　　net.sf.hibernate.transaction.JTATransactionFactory <br>　　#hibernate.transaction.factory_class <br>　　net.sf.hibernate.transaction.JDBCTransactionFactory <br><br>　　在下面的分析中我会给出原因。 <br><br>　　<strong>一、JDBC Transaction <br></strong><br>　　看看使用JDBC Transaction的时候我们的代码例子： <br><br>　　Session session = sf.openSession(); <br>　　Transaction tx = session.beginTransactioin(); <br>　　... <br>　　session.flush(); <br>　　tx.commit(); <br>　　session.close(); <br><br>　　这是默认的情况，当你在代码中使用Hibernate的Transaction的时候实际上就是JDBCTransaction。那么JDBCTransaction究竟是什么东西呢？来看看源代码就清楚了： <br><br>　　Hibernate2.0.3源代码中的类 <br><br>　　net.sf.hibernate.transaction.JDBCTransaction: <br><br>　　public void begin() throws HibernateException { <br>　　... <br>　　if (toggleAutoCommit) session.connection().setAutoCommit(false); <br>　　... <br>　　} <br><br>　　这是启动Transaction的方法，看到 connection().setAutoCommit(false) 了吗？是不是很熟悉？ <br><br>　　再来看 <br><br>　　public void commit() throws HibernateException { <br>　　... <br>　　try { <br>　　if ( session.getFlushMode()!=FlushMode.NEVER ) session.flush(); <br>　　try { <br>　　session.connection().commit(); <br>　　committed = true; <br>　　} <br>　　... <br>　　toggleAutoCommit(); <br>　　} <br><br>　　这是提交方法，看到connection().commit() 了吗？下面就不用我多说了，这个类代码非常简单易懂，通过阅读使我们明白Hibernate的Transaction都在干了些什么？我现在把用Hibernate写的例子翻译成JDBC，大家就一目了然了： <br><br>　　Connection conn = ...; &lt;--- session = sf.openSession(); <br>　　conn.setAutoCommit(false); &lt;--- tx = session.beginTransactioin(); <br>　　... &lt;--- ... <br>　　conn.commit(); &lt;--- tx.commit(); (对应左边的两句) <br>　　conn.setAutoCommit(true); <br>　　conn.close(); &lt;--- session.close(); <br><br>　　看明白了吧，Hibernate的JDBCTransaction根本就是conn.commit而已，根本毫无神秘可言，只不过在Hibernate中，Session打开的时候，就会自动conn.setAutoCommit(false)，不像一般的JDBC，默认都是true，所以你最后不写commit也没有关系，由于Hibernate已经把AutoCommit给关掉了，所以用Hibernate的时候，你在程序中不写Transaction的话，数据库根本就没有反应。 <br><br>　　<strong>二、JTATransaction <br></strong><br>　　如果你在EJB中使用Hibernate，或者准备用JTA来管理跨Session的长事务，那么就需要使用JTATransaction，先看一个例子： <br><br>　　javax.transaction.UserTransaction tx = new <br>　　InitialContext().lookup("javax.transaction.UserTransaction"); <br>　　Session s1 = sf.openSession(); <br>　　... <br>　　s1.flush(); <br>　　s1.close(); <br>　　... <br>　　Session s2 = sf.openSession(); <br>　　... <br>　　s2.flush(); <br>　　s2.close(); <br>　　tx.commit(); <br><br>　　这是标准的使用JTA的代码片断，Transaction是跨Session的，它的生命周期比Session要长。如果你在EJB中使用Hibernate，那么是最简单不过的了，你什么Transaction代码统统都不要写了，直接在EJB的部署描述符上配置某某方法是否使用事务就可以了。 <br><br>　　现在我们来分析一下JTATransaction的源代码， net.sf.hibernate.transaction.JTATransaction: <br><br>　　public void begin(InitialContext context, ... <br>　　... <br>　　ut = (UserTransaction) context.lookup(utName); <br>　　... <br><br>　　看清楚了吗？ 和我上面写的代码 tx = new Initial Context?().lookup("javax.transaction.UserTransaction"); 是不是完全一样？ <br><br>　　public void commit() ... <br>　　... <br>　　if (newTransaction) ut.commit(); <br>　　... <br><br>　　JTATransaction的控制稍微复杂，不过仍然可以很清楚的看出来Hibernate是如何封装JTA的Transaction代码的。 <br><br>　　但是你现在是否看到了什么问题？ 仔细想一下，Hibernate Transaction是从Session中获得的，tx = session.beginTransaction()，最后要先提交tx，然后再session.close，这完全符合JDBC的Transaction的操作顺序，但是这个顺序是和JTA的Transactioin操作顺序彻底矛盾的！！！ JTA是先启动Transaction，然后启动Session，关闭Session，最后提交Transaction，因此当你使用JTA的Transaction的时候，那么就千万不要使用Hibernate的Transaction，而是应该像我上面的JTA的代码片断那样使用才行。 <br><br>　　总结： <br><br>　　1、在JDBC上使用Hibernate 必须写上Hibernate Transaction代码，否则数据库没有反应。此时Hibernate的Transaction就是Connection.commit而已 <br><br>　　2、在JTA上使用Hibernate 写JTA的Transaction代码，不要写Hibernate的Transaction代码，否则程序会报错 <br><br>　　3、在EJB上使用Hibernate 什么Transactioin代码都不要写，在EJB的部署描述符里面配置 <br><br>　　|---CMT(Container Managed Transaction) <br>　　| <br>　　|---BMT(Bean Managed Transaction) <br>　　| <br>　　|----JDBC Transaction <br>　　| <br>　　|----JTA Transaction <br clear=all>
<img src ="http://www.blogjava.net/jesson2005/aggbug/113519.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jesson2005/" target="_blank">张金鹏</a> 2007-04-25 14:11 <a href="http://www.blogjava.net/jesson2005/articles/113519.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>