<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
    主站蜘蛛池模板: 激情内射亚洲一区二区三区| 亚洲欧洲精品成人久久曰影片 | 无码午夜成人1000部免费视频| 亚洲第一页日韩专区| 免费无码午夜福利片| 免费在线观看亚洲| 免费看一级一级人妻片| 亚洲天堂在线视频| 四虎国产精品免费永久在线| 国产亚洲免费的视频看| 一区二区三区四区免费视频| 亚洲女人初试黑人巨高清| 希望影院高清免费观看视频| 亚洲国产精品一区二区三区在线观看 | 亚洲成人一区二区| 一级特黄aaa大片免费看| 亚洲无人区一区二区三区| 在线观看肉片AV网站免费| 亚洲色欲色欲综合网站| 999久久久免费精品国产| 亚洲日韩乱码中文字幕| 免费国产成人午夜私人影视 | 亚洲国产成人久久综合一区77 | 亚洲午夜一区二区三区| 永久黄网站色视频免费| 永久免费观看黄网站| 亚洲乱码一区二区三区在线观看| 日韩精品人妻系列无码专区免费| 国产成人精品亚洲日本在线| 狠狠久久永久免费观看| 亚洲黄片手机免费观看| 亚洲图片校园春色| 一本久到久久亚洲综合| 小日子的在线观看免费| 亚洲日韩av无码中文| 国产啪亚洲国产精品无码| 五月亭亭免费高清在线| 免费福利资源站在线视频| 亚洲福利视频导航| 性做久久久久免费观看| 免费看搞黄视频网站|