如鵬網 大學生計算機學習社區

          CowNew開源團隊

          http://www.cownew.com 郵件請聯系 about521 at 163.com

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            363 隨筆 :: 2 文章 :: 808 評論 :: 0 Trackbacks

          Spring 事務管理創造性的解決了很多以前要用重量級的應用服務器才能解決的事務問題,那么其實現原理一定很深奧吧?可是如果讀者仔細研究了Spring事務管理的代碼以后就會發現,事務管理其實也是如此簡單的事情。這也印證了在本書開頭的一句話“重劍無鋒、大巧不工”,Spring并沒有使用什么特殊的API,它運行的原理就是事務的原理。下面是DataSourceTransactionManager的啟動事務用的代碼(經簡化):
          protected void doBegin(Object transaction, TransactionDefinition definition)
          {
          ?DataSourceTransactionObject txObject =
          (DataSourceTransactionObject) transaction;
          ?Connection con = null;
          ?try
          ?{
          ??if (txObject.getConnectionHolder() == null)
          ??{
          ???Connection newCon = this.dataSource.getConnection();
          ???txObject.setConnectionHolder(
          new ConnectionHolder(newCon), true);
          ??}
          ??txObject.getConnectionHolder()
          .setSynchronizedWithTransaction(true);
          ??con = txObject.getConnectionHolder().getConnection();

          ??Integer previousIsolationLevel = DataSourceUtils
          ?????.prepareConnectionForTransaction(con, definition);
          ??txObject.setPreviousIsolationLevel(previousIsolationLevel);
          ??if (con.getAutoCommit())
          ??{
          ???txObject.setMustRestoreAutoCommit(true);
          ???con.setAutoCommit(false);
          ??}
          ??txObject.getConnectionHolder().setTransactionActive(true);
          ??// Bind the session holder to the thread.
          ??if (txObject.isNewConnectionHolder())
          ??{
          ???TransactionSynchronizationManager.bindResource(
          getDataSource(),txObject.getConnectionHolder());
          ??}
          ?}
          ?catch (SQLException ex)
          ?{
          ??DataSourceUtils.releaseConnection(con, this.dataSource);
          ??throw new CannotCreateTransactionException(
          ?????"Could not open JDBC Connection for transaction", ex);
          ?}
          }
          本文出自:http://www.cownew.com
          在調用一個需要事務的組件的時候,管理器首先判斷當前調用(即當前線程)有沒有一個事務,如果沒有事務則啟動一個事務,并把事務與當前線程綁定。Spring使用TransactionSynchronizationManager的bindResource方法將當前線程與一個事務綁定,采用的方式就是ThreadLocal,這可以從TransactionSynchronizationManager類的代碼看出。
          public abstract class TransactionSynchronizationManager
          {
          ?……
          ?private static final ThreadLocal currentTransactionName = new ThreadLocal();
          ?private static final ThreadLocal currentTransactionReadOnly = new ThreadLocal();
          ?private static final ThreadLocal actualTransactionActive = new ThreadLocal();?……
          }
          從doBegin的代碼中可以看到在啟動事務的時候,如果Connection是的自動提交的(也就是getAutoCommit()方法返回true)則事務管理就會失效,所以首先要調用setAutoCommit(false)方法將其改為非自動提交的。setAutoCommit(false)這個動作在有的JDBC驅動中會非常耗時,所以最好在配置數據源的時候就將“autoCommit”屬性配置為true。

          posted on 2007-01-02 23:33 CowNew開源團隊 閱讀(3234) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 扎囊县| 清水河县| 阳西县| 泾川县| 东乡县| 呼和浩特市| 安远县| 景泰县| 盐城市| 临夏县| 博湖县| 忻州市| 交口县| 吉林省| 南陵县| 枣庄市| 婺源县| 鄂托克前旗| 获嘉县| 泗洪县| 苏尼特左旗| 昔阳县| 水富县| 杭州市| 新竹县| 得荣县| 磐石市| 华坪县| 五寨县| 罗平县| 宝清县| 玉龙| 胶南市| 察隅县| 阿巴嘎旗| 婺源县| 太康县| 浪卡子县| 彰化市| 永靖县| 河间市|