<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    歲月如哥
    人生非夢
    posts - 50,comments - 144,trackbacks - 0
    背景: 
        XX系統實施一段時間之后,出現數據連接池滿,第一次通過修改if(con!=null && con.isClosed()){con.close();}這樣的邏輯錯誤解決部分問題。第二次通過徹底復查代碼,修改了connection、session沒有釋放的問題,基本上保證我們自己寫的代碼沒有數據庫連接不釋放的問題。但是臨近近期還是出現連接池滿的問題。。。

    過程:
        從日志看,除了有大量工作流報錯之外程序很少有異常,類似如下:
    引用:
    2009-06-12 15:44:34,187 [http-80-Processor44] [org.hibernate.event.def.AbstractFlushingEventListener] [ERROR] - Could not synchronize database state with session
    org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [org.jbpm.graph.exe.Token#35000000000033432]
             ..............................................
            at org.jbpm.persistence.db.DbPersistenceService.close(DbPersistenceService.java:180)
             ..............................................
    2009-06-12 15:44:34,187 [http-80-Processor44] [org.jbpm.svc.Services] [ERROR] - problem closing service 'persistence'
    org.jbpm.persistence.JbpmPersistenceException: couldn't flush hibernate session
            at org.jbpm.persistence.db.DbPersistenceService.close(DbPersistenceService.java:182)

    Caused by: org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [org.jbpm.graph.exe.Token#35000000000033432]
            at org.jbpm.persistence.db.DbPersistenceService.close(DbPersistenceService.java:180)
            ... 54 more
    最開始基本確定了是工作流報錯導致數據庫連接池不釋放,理由:
            a、上面的錯和hibernate的session有關
            b、在sybase執行sp_who發現大量不釋放連接所占用的庫為DB_LC,而這個庫就是工作流相關的庫。
            c、從sybase的sysprocesses表查看,不釋放連接是每天新增10-30不等,隨機統計了日志某天的如前所述的異常為27個,而從數據庫端統計該天新增連接也是27個。
         因為自己對工作流不熟悉,所以每次都是把情況反映給相關人員處理。前幾天去客戶現場正好抓取了一下不釋放連接正在執行的sql,基本都是亂碼,如下:
    引用:
    DBCC execution completed. If DBCC printed error messages, contact a user with System Administrator (SA) role.
    SQL Text: !
    DBCC execution completed. If DBCC printed error messages, contact a user with System Administrator (SA) role.
    (1 row affected)
    47
    DBCC execution completed. If DBCC printed error messages, contact a user with System Administrator (SA) role.
    SQL Text: *
    DBCC execution completed. If DBCC printed error messages, contact a user with System Administrator (SA) role.
    (1 row affected)
    49
    DBCC execution completed. If DBCC printed error messages, contact a user with System Administrator (SA) role.
    SQL Text: 
    DBCC execution completed. If DBCC printed error messages, contact a user with System Administrator (SA) role.
    (1 row affected)
    這個結果用處不大,很好奇這個問題,所以找了一份工作流的源碼,找到報錯的類DbPersistenceService.close方法,如下:
    復制內容到剪貼板
    代碼:
    public void close() {
        if ( (session!=null)
             && (transaction==null)
             && (isRollbackOnly)
           ) {
          throw new JbpmException("setRollbackOnly was invoked while configuration specifies user managed transactions");
        }
        if (messagingSession!=null) {
          messagingSession.closeOpenIterators();
        }
        if (schedulerSession!=null) {
          schedulerSession.closeOpenIterators();
        }
        if ( (isTransactionEnabled)
             && (transaction!=null)
           ) {
          if (isRollbackOnly) {
            try {
              log.debug("rolling back hibernate transaction");
              mustSessionBeFlushed = false; // flushing updates that will be rolled back is not very clever :-)
              transaction.rollback();
            } catch (Exception e) {
              throw new JbpmPersistenceException("couldn't rollback hibernate session", e);
            }
          } else {
            try {
              log.debug("committing hibernate transaction");
              mustSessionBeFlushed = false; // commit does a flush anyway
              transaction.commit();
            } catch (Exception e) {
              try {
                // if the commit fails, we must do a rollback
                transaction.rollback();
              } catch (Exception e2) {
                // if the rollback fails, we did what we could and you're in
                // deep shit :-(
                log.error("problem rolling back after failed commit", e2);
              }
              throw new JbpmPersistenceException("couldn't commit hibernate session", e);
            }
          }
        }
       
        if (mustSessionBeFlushed) {
          try {
            log.debug("flushing hibernate session");
            session.flush();
          } catch (Exception e) {
            throw new JbpmPersistenceException("couldn't flush hibernate session", e);
          }
        }   
        if (mustSessionBeClosed) {
          try {
            log.debug("closing hibernate session");
            session.close();
          } catch (Exception e) {
            throw new JbpmPersistenceException("couldn't close hibernate session", e);
          }
        }

        if (mustConnectionBeClosed) {
          try {
            log.debug("closing jdbc connection");
            connection.close();
          } catch (Exception e) {
            throw new JbpmPersistenceException("couldn't close jdbc connection", e);
          }
        }
      }
    一看真是嚇一跳,程序在執行到session.flush();時候報錯的話,如果mustSessionBeClosed為true根本不能執行到后面的session.close(),會導致數據庫連接不釋放的問題……基本確定問題所在了,就在本地試著復現一下問題(因為前面所描述的異常在開發環境無法復現,所以只能強制在flush后拋異常),果然不出意料。
         因為這個是jbpm3.1.2版本,覺得應該是jbpm的bug吧,就又下載了一份jbpm3.3.0GA源碼,找到DbPersistenceService.close()方法:
    復制內容到剪貼板
    代碼:
      public void close() {

        if ( (session!=null)
             && !isTransactionActive()
             && (isRollbackOnly())
           ) {
          throw new JbpmException("setRollbackOnly was invoked while configuration specifies user managed transactions");
        }
       
        if ( (isTransactionEnabled)
             && (transaction!=null)
           ) {

          if (! isRollbackOnly()) {
            Exception commitException = commit();
            if (commitException!=null) {
              rollback();
              closeSession();
              closeConnection();
              throw new JbpmPersistenceException("hibernate commit failed", commitException);
            }

          } else { // isRollbackOnly==true
            Exception rollbackException = rollback();
            if (rollbackException!=null) {
              closeSession();
              closeConnection();
              throw new JbpmPersistenceException("hibernate rollback failed", rollbackException);
            }
          }
        }
       
        Exception flushException = flushSession();
        if (flushException!=null) {
          // JBPM-1465 transaction has been either committed or rolled back at this point
          // on the other hand, it is possible that no transaction is underway
          // hence rolling back here is redundant and possibly dangerous
          closeSession();
          closeConnection();
          throw new JbpmPersistenceException("hibernate flush failed", flushException);
        }
        Exception closeSessionException = closeSession();
        if (closeSessionException!=null) {
          closeConnection();
          throw new JbpmPersistenceException("hibernate close session failed", closeSessionException);
        }
        Exception closeConnectionException = closeConnection();
        if (closeConnectionException!=null) {
          throw new JbpmPersistenceException("hibernate close connection failed", closeConnectionException);
        }
      }
    果然在3.3.0版本中,當flush、close等操作出現異常時候,都會調用closeSession()和closeConnection()以保證連接正常釋放。照貓畫虎在該方法寫了關閉session和connection的方法,準備月底發布新版本試試。

    結論:
       XX系統工作流jbpm3.1.2存在連接不釋放的bug,當然前提是程序執行數據庫操作報錯的情況下(如session.flush)。雖然解決了連接不釋放的問題,但是這個關于這個報錯的深層原因還沒搞清楚。另外和相關人員確認,工作流的這些異常可以cacth掉,到目前為止除了引起連接不釋放之外,沒有發現其他問題。
    posted on 2009-06-22 17:38 歲月如歌 閱讀(1865) 評論(0)  編輯  收藏 所屬分類: java
    主站蜘蛛池模板: 99久久99这里只有免费费精品| 拍拍拍无挡视频免费观看1000| 中文字幕无码播放免费| 亚洲AV无码专区国产乱码电影| 国产精品午夜免费观看网站| 亚洲国产成人久久一区WWW| 免费在线观看亚洲| 亚洲国产成人久久综合碰| 一级人做人a爰免费视频 | 91在线视频免费91| 亚洲人成人网毛片在线播放| 搡女人免费视频大全| 含羞草国产亚洲精品岁国产精品| 免费在线不卡视频| 两性色午夜免费视频| 久久久久久亚洲Av无码精品专口| 中文字幕免费在线看线人| 亚洲精品国产首次亮相| 免费国产成人高清视频网站 | 久久精品国产免费| 亚洲福利秒拍一区二区| 曰批视频免费30分钟成人| 亚洲性无码AV中文字幕| 久久久久亚洲av成人无码电影| 国产精品网站在线观看免费传媒| 亚洲日本国产精华液| 在线免费观看韩国a视频| 国产在线精品一区免费香蕉| 亚洲黄网在线观看| 无码欧精品亚洲日韩一区夜夜嗨 | 亚洲精品无码乱码成人| 嫖丰满老熟妇AAAA片免费看| 欧美色欧美亚洲另类二区| 国产亚洲精品精品国产亚洲综合 | 国产国产人免费人成免费视频 | 女人18毛片a级毛片免费视频| 日韩在线观看免费完整版视频| 五月天网站亚洲小说| 国产中文字幕免费| 免费不卡在线观看AV| 欧洲精品码一区二区三区免费看|