## 一、與主程序事務沖突問題
典型的,如果我們部署一套主程序,一套jobserver或者workserver等,由于兩者共享同一個數據庫,而兩者由于各自事務中,如果一方有某個長時間事務性(比如循環的全表掃描)的鎖定某張表的操作,而恰恰對方的業務中需要訪問該表,就會拋出 com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction。
解決的方案:將jobserver中,全表掃描的操作,改為短事務,簡單的做法,就是循環全表掃描的過程中,每次操作都是一個完整事務的,而不是全部操作放在一個事務里面,更具體來說,就是事務部放到manager層面,而是放在dao層面。
具體的例子:
Manager層面:
事務的:


非事務的:


注意,這里面的dao必須是事務的了,否則,無法修改、刪除、新增實體對象。
Job層面:
事務的:

非事務的:

非事務中,對實體的操作:

但是,這里還是有一個問題,就是由于事務控制在dao層面,會導致每個dao操作都會提交事務,對于每一輪循環操作里面組合了若干個dao操作的,這樣會出現事務臟數據的問題。
解決的方案是:
繼續抽取api,將循環體里面的所有dao操作組合起來,合并為一個api,將事務控制,由原dao層面,提升到該api的事務操作類層面,并將該事務操作類納入applicationContext-*.xml里面,通過serviceLocator.getObjectFromContext獲取即可。

這個方案確保了循環體里面的操作都是完整的事務,循環體之間不是同一個事務,兼顧了事務完整性和避免長事務。
## 二、事務內死循環問題
死循環的操作,除了上述問題之外,即使是一張獨占的表,還會帶來事務永遠無法提交的問題,所以不能用死循環的方式來處理長時間事務的。
比如:


這個方案里面,由于doTest永遠無法結束,導致內部的事務無法提交,一直處于事務中。故不能采用這種方案,只能是用減小間隔的方式。
## 三、多job之間事務并發機制
多個job中,如果都循環操作同一個表,會出現臟數據的問題,比如某個job修改后,另外一個job拿到了繼續修改,但由于事務未提交,會出現臟數據。
解決辦法,用數據庫的鎖機制解決。平臺推薦用樂觀鎖,增加版本號來解決沖突。具體可以參考《高級指南》中的樂觀鎖悲觀鎖章節了解;
## 四、全局單一事務job
有時候,有些業務并非長事務,但需要保障業務事務的完整性,平臺提供了一種單一事務job機制。該job里面所有業務邏輯,都在一個事務里面執行,如果執行過程有異常,則會回滾;
具體做法如下:
1、該job與普通job不同,繼承自UniframeworkTimerSingleTransactionJob
2、實現自己的事務內操作,實現自己的SingleTransactionJobOperator類
示例如下:

## 五、循環獨立事務job
對于長時間的事務,整個job的執行跨度非常長(參考4.1),循環遍歷業務,且每個循環的業務都各自獨立,互補影響,那么,就非常適合用循環獨立事務job,job里面的業務,通過循環來實現,每一輪循環體內的業務,在一個事務里面執行,如果執行過程有異常,則僅循環體內事務回滾,不影響整體job的執行;
具體做法如下:
1、job繼承自UniframeworkTimerJob
2、定義自己的manager,logic及api;
各種定義配置如下:

代碼實現的時候,特別注意,異常的處理,在logic循環內來處理,否則,因為api層面必須拋出異常,才能實現事務回滾,所以不可以在api里面來處理異常,直接讓它拋出即可;
具體的實例明細如下:
Job:

Manager:

Logic:

這里是關鍵,這里處理異常,確保不會因為一次失敗,終止整個調度,僅終止該次循環的調度邏輯,而且能確保該次邏輯也是完整事務的,出錯會回滾;這里是在循環體內,捕捉每次api調用的異常;
Api:

Api里面,不要處理異常,直接拋出即可;
## 六、跨數據源job
在一個job中,跨兩個數據庫進行操作;
首先、uniframework.properties中配置;

server.jobserver.anotherds.enabled必須設定為true,才會加載;
然后、在job中,調用第二數據源的dao,即可;
this.serviceLocator.getJobserverAnotherDatasourceDao()
舉例如下:
核心業務代碼中,這樣來調用第二數據源:

- 前言
- 01、系統平臺
- 系統管理
- 組織類型
- 單位管理
- 基本功能
- SAAS功能
- 組織管理
- 角色管理
- 人員管理
- 賬號管理
- 賬戶體系
- 賬號綁定
- 賬號鎖定
- 團隊管理
- 模板管理
- 補丁管理
- 字段管理
- 靜態字典
- 動態字典
- 系統配置
- 菜單配置
- 路由配置
- 編碼規則
- 訪問控制
- 系統參數
- 字典配置
- 參數定義
- 參數配置
- 屬性定義
- 屬性設置
- 樹形定義
- 樹形設置
- 系統監控
- 業務維護
- 工作監控
- 調度監控
- 導入監控
- 日志管理
- 在線監控
- 附件管理
- 附件監控
- 附件應用
- 附件授權
- 上傳監控
- 字段監控
- 系統提醒
- 場景配置
- 事件監控
- 提醒記錄
- 事件歷史
- 日期設置
- 節假日期
- 工作時間
- 日歷編制
- 工作日歷
- 開放平臺
- 微信應用
- 配置信息
- 更新菜單
- 釘釘應用
- 配置信息
- 開放服務
- 應用設置
- 服務管理
- 請求監控
- 請求跟蹤
- 移動應用
- 發布管理
- 導航菜單
- 個人管理
- 個人資料
- 內部消息
- 短信中心
- 流程管理
- 流程定義
- 流程環節
- 處理人
- 流程提醒
- 流程簽收
- 流程目錄
- 流程微調
- 轉移動作
- 定義校驗
- 流程綁定
- 流程實體設定
- 單業務多流程
- 動態表單綁定
- 環節字段設定
- 轉移路由設定
- 流程監控
- 流程催辦
- 流程會話
- 流程啟動
- 通用待辦
- 流程驅動
- 通用已辦
- 示范實例
- 流程啟動
- 流程待辦
- 流程已辦
- 常見問題
- 表單管理
- 預留字段
- 字段定義
- 業務應用
- 動態輔表
- 輔表定義
- 輔表應用
- 輔表監控
- 動態主表
- 主表定義
- 業務定義
- 元數據
- 產生機制
- 應用場景
- 02、技術平臺
- 重要組件
- 表單引擎
- 流程引擎
- 基礎設施
- 系統安全
- 服務集成
- 核心組件
- 核心平臺
- 調度容器
- 代碼調試
- 相關配置
- 常見問題
- 多線程
- 工作容器
- 開放服務
- 富客戶端
- 代理容器
- https
- SSLPinning
- 03、手機應用
- 參數配置
- 技術平臺
- 功能設計
- 系統功能
- 應用升級
- 業務模塊
- 04、微信應用
- 參數配置
- 多公眾號
- 技術平臺
- 業務功能
- 平臺功能
- 微信客服
- 微信公號
- 05、開放服務
- 接入示例
- 實施方案
- nginx安裝
- nginx配置
- nginx運行
- nginx限流
- 實現方案
- 業務操作
- 代碼示意
- 06、常見問題
- 性能優化
- 啟動優化
- 解決方案
- 實體操作沖突
- 算法說明
- 檢驗算法
- 注意事項
- 瀏覽器
- 插件
- 郵箱配置
- 系統維護
- 維護日志
- 維護腳本
- 開發環境
- 07、版權信息
- 平臺版權
- 產品版權
- 后記