JBPM數據庫中每一個表都有一個主鍵-ID(Long類型)。這個ID是可以由用戶自己產生,也可以由JBPM產生。這個數值在所有表的ID中是唯一的。用戶通過設定jbpm.id.generator屬性來設定id產生的類。
(一)JBPM ID生成基本原理和函數
JBPM中ID產生的基本原理是:用表JBPM_SEQUENCEBLOCK存儲當前可用的ID值,JBPM需要使用ID時,從數據庫中取得這個ID,然后增加一定的數量作為當前可用ID值,并存儲在數據庫中。JBPM的ID可以用于服務器集群的情況。hibernate中產生ID的函數IncrementGenerator,原理與JBPM產生ID相似,但不能應用到集群的情況。
JBPM_SEQUENCEBLOCK表有兩個字段ID和NextID,前者為主鍵,表示當前節點在集群中的ID號碼,后者為當前節點可以使用數據段的最小數。表由類org.jbpm.persistence.hibernate.SequenceBolck代表,org.jbpm.persistence.hibernate.SequenceBolckIdGenerator維護。
SequenceBolckIdGenerator主要函數:
(1) public SequenceBlockIdGenerator(JbpmConfiguration jbpmConfiguration)
初始化,包括初始化nodeId 和blockSize變量。nodeId指明當前的節點在集群中的Id號(0-65535),用戶可以通過jbpm.id.nodeId設定,缺省值是0。BlockSize指明當前節點使用長整形數段的一個數據塊大小,用戶可以通過jbpm.id.bolckSize設定,缺省值是100。
(2) public long getNextId() //得到當前可用ID,JBPM使用它得到ID
{
return getNextId(sessionFactory, nodeId, blockSize);
}
(3)public static synchronized long getNextId(SessionFactory sessionFactory,
long nodeId, long blockSize)
最重要的函數,用于計算當前可用ID。
(二)ID產生算法
基本思路:將1-Long.MaxValue范圍內數,按大小blockSize*MaxNodes分段,然后再將每一段按blockSize大小分成MaxNodes塊,各節點按照節點號分塊使用,如節點號為0的只能使用第一塊,節點號為1的使用第二塊,依次類推。MaxNodes為當前集群中的節點總數,為65535。
取值算法:
(1) 取出節點當前可以使用數塊的首數(塊的最小數);
(2) 首數+blockSize×NodeId(節點號碼,0-65535)為當前可以使用的Id(nextId);
(3) nextId+blockSize-1為當前可以使用的最后一個Id(lastId)
(4) 調用getNextId()函數時,假如nextId<=lastId,則返回nextId,然后將nextId++;否則取出下一數據塊進行1-3的計算。
說明:
(1) 讀取一次數據庫,可以使用blockSize個Id,不用每次使用ID都讀取一次數據庫。
(2) 表的NextID字段存儲的是當前可使用塊而不是使用過塊的首數。每個節點使用塊的首數按節點號碼分別存儲。
(3) 對于每一個數塊,每個節點只使用其中一部分,范圍是(首數+blockSize×NodeId)-(首數+blockSize×(NodeId+1)-1),從而保證了每個節點使用的ID值在數據庫中是唯一的。
(三)數據庫連接Session
為了保證產生ID的唯一性,JBPM要求對表JBPM_SEQUENCEBLOCK進行操作的數據庫Session必須是獨立的,不能用于其它的數據庫操作。假如JBPM使用數據庫連接池,則必須要設定jbpm.id.generator.configuration屬性,提供進行數據庫直接連接的hibernate配置文件。默認情況下,JBPM使用一個全局靜態Session進行除JBPM_SEQUENCEBLOCK以外表的操作,而對JBPM_SEQUENCEBLOCK表進行操作的Session是在類SequenceBolckIdGenerator初始化時臨時建立的。.
新聞熱點
疑難解答