空間站

          北極心空

            BlogJava :: 首頁 :: 聯系 :: 聚合  :: 管理
            15 Posts :: 393 Stories :: 160 Comments :: 0 Trackbacks
          ?????????????????????????????????????????? 事務管理最佳實踐多余的話之一
          ????????????????????????????????????????? ? ----“每次請求,一次數據庫連接,一次事務”是不是金科玉律?
          前言
          《事務管理最佳實踐多余的話之一》,不知道會不會還有之二、之三。
          ?
          “每次請求,一次數據庫連接,一次事務”是不是金科玉律?
          “每次請求,一次數據庫連接,一次事務”,這只是一個大體的原則,表示我們的數據庫連接和事務在一個請求的范圍內,應該盡可能得長。并不是一定要你遵循這個原則。所有的原則、理論,只是指導你工作的思想武器,決不是約束你的條條框框。面對具體情況,你可以靈活處理。
          完全可以這樣做:“每次請求,多次數據庫連接,多次事務”。
          請看下面這個例子:
          ?
          一、這是SpringMVC的一個控制器的方法
          前臺頁面上是一個多選框,選中多個要刪除的工作流。傳遞的參數,是各個工作流的名字。
          這里,在循環中調用服務類的Transaction方法:uninstallJbpmProcessDefinitionsTransaction(names[i])
          卸載Jbpm的業務程序定義,及其全部實例、任務。
          /**
          ?????*刪除該頁選中的業務程序定義
          ?????*@paramrequest
          ?????*@paramresponse
          ?????*
          @return
          ?????*@throwsException
          ?????
          */
          ????
          public?ModelAndView?uninstall(HttpServletRequest?request,HttpServletResponse?response,ProcessDefinitionNames?command)?throws?Exception{
          ????
          /**
          ?????*1,選中的工作流名字。
          ?????
          */
          ????String[]?names
          =command.getNames();
          ????
          for(int?i=0;i<names.length;i++){
          ????????
          this.getUninstallProcessDefinition().uninstallJbpmProcessDefinitionsTransaction(names[i]);
          ????????
          ????}
          ????
          ???????
          ???????returnnew?ModelAndView(UrlMap.map(
          "manage.uninstallProcessDefinition.uninstall"));
          ????}
          ?

          二、這是服務類的相關方法
          (一)這是服務類的Transaction方法。創建和關閉了Hibernate的Session,同時也處理了事務。

          /*?(non-Javadoc)
          ?????*?@see?com.withub.common.util.IUninstallProcessDefinition#uninstallJbpmProcessDefinitionsTransaction(java.lang.String)
          ?????
          */
          ?????publicvoid?uninstallJbpmProcessDefinitionsTransaction(String?name){
          ????????JbpmContext?jbpmContext?
          =?JbpmConfiguration.getInstance().createJbpmContext();
          ???????????
          try?{
          ???????????
          ???????????
          this.uninstallJbpmProcessDefinitionsDao(name);
          ????????????????????
          ???????????}
          finally{
          ???????????jbpmContext.close();
          ???????????
          ???????????}
          ????????
          ?????}
          (二)這是具體使用Hibernate的數據訪問方法,執行卸載業務程序定義的方法。
          控制器層不能直接調用它,因為它沒有提供處理“得到和關閉數據庫連接,管理事務”任務的代碼。

          /**
          ?????*
          ?????*@paramname
          ?????
          */
          ????privatevoid?uninstallJbpmProcessDefinitionsDao(String?name){
          ???????JbpmContext?jbpmContext?
          =?JbpmConfiguration.getInstance().getCurrentJbpmContext();
          ???????GraphSession?graphSession
          =jbpmContext.getGraphSession();
          ????????List?processDefinitions
          =graphSession.findAllProcessDefinitionVersions(name);
          ????????
          if(processDefinitions!=null){
          ????????Iterator?iterator
          =processDefinitions.iterator();
          ?????????
          while(iterator.hasNext()){
          ?????????????
          ?????????????graphSession.deleteProcessDefinition((ProcessDefinition)iterator.next());
          ????????}
          ????????
          ????????
          ????????}
          ????????log.info(
          "卸載工作流:"+name);
          ????}

          例子解析
          上面這個例子中,控制器中,每一次循環,都重復執行了“得到和關閉數據庫連接,管理事務”的代碼。因此,違背了“每次請求,一次數據庫連接,一次事務”的原則。
          依照這個原則,我們需要在服務類中重新寫一個Transaction方法,把所有循環放在try塊中。只使用一個數據庫連接和事務。
          這樣做,當然可以。但是,上面的代碼也沒有什么問題。如果在控制器方法執行過程中,發生異常,那么可能有的Jbpm工作流定義(我叫它們為“業務程序定義”)被卸載了,有的沒有被卸載。但是,這不會破壞數據庫中數據的完整性和正確性。
          上面這段代碼,唯一的問題是,數據庫連接的獲取和關閉太頻繁。但是,根據這個控制器方法的業務邏輯,我們知道,這個循環并不會太大。因為,要卸載的業務程序定義不可能很多。而且,這個功能的前臺頁面是分頁的,因此,不會一次卸載太多的業務程序定義。所以,這個問題并不是很嚴重。
          既然如此,基于實用主義的原則,我不打算修改上面的代碼。這樣,我就減少了編寫一個Service類的Transaction方法的麻煩。現在使用的這個Transaction方法是原來就開發好的。(為了一個命令行卸載工具開發的)
          ?
          結語
          這篇“多余的話”,就是希望讀者不要走極端。在理想主義和現實情況之間,我們應該用現實主義的方法來看待問題,解決問題。“不管白貓黑貓,抓住老鼠就是好貓”!當然,在現實生活中,我還是希望你能夠想得更深一點,永遠保持“精益求精”的精神,多問問為什么,怎樣才能做得更好。這樣,才能有助于你進一步提高。
          我記得《代碼大全》的作者Steve McConnell,曾經說過(我不記得原話了,大概就是下面我說的這個意思):一個程序員的能夠達到的成就,從他從業的第一年就可以看出來。一個程序員,在從業一年之后,應該已經可以勝任大部分工作。如果他不再追求更好的編碼,只是得過且過,吃老本,那么這個程序員不管從業多少年,永遠只是菜鳥級的。如果一個程序員,在從業兩年之后,依然保持著旺盛的求知欲,那么他的前途將是無可限量的!
          希望你是后者,當然,如果你想轉作管理,那么選擇作前者,你的“錢途”更加光明!
          ?
          ?


          Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1417657

          posted on 2006-12-02 17:10 蘆葦 閱讀(560) 評論(0)  編輯  收藏 所屬分類: Spring
          主站蜘蛛池模板: 华容县| 旺苍县| 阿城市| 那曲县| 宜良县| 定陶县| 麦盖提县| 榕江县| 秦皇岛市| 襄樊市| 永靖县| 永嘉县| 多伦县| 松原市| 厦门市| 南平市| 无锡市| 新绛县| 民和| 岫岩| 曲松县| 古蔺县| 周口市| 宣化县| 禄丰县| 菏泽市| 盐源县| 赤城县| 三亚市| 巨野县| 比如县| 绥芬河市| 平果县| 永和县| 会宁县| 尉氏县| 苍梧县| 鲁甸县| 镇原县| 温泉县| 邢台县|