JBPM源码分析(一)---数据库表主键ID的产生机制
2008-01-05 18:48:07 来源:WEB开发网 闂傚倸鍊搁崐鎼佸磹閹间礁纾归柟闂寸绾惧綊鏌熼梻瀵割槮缁炬儳缍婇弻鐔兼⒒鐎靛壊妲紒鐐劤缂嶅﹪寮婚悢鍏尖拻閻庨潧澹婂Σ顔剧磼閻愵剙鍔ょ紓宥咃躬瀵鎮㈤崗灏栨嫽闁诲酣娼ф竟濠偽i鍓х<闁诡垎鍐f寖闂佺娅曢幑鍥灳閺冨牆绀冩い蹇庣娴滈箖鏌ㄥ┑鍡欏嚬缂併劎绮妵鍕箳鐎n亞浠鹃梺闈涙搐鐎氫即鐛崶顒夋晬婵絾瀵ч幑鍥蓟閻斿摜鐟归柛顭戝枛椤牆顪冮妶搴′簼缂侇喗鎸搁悾鐑藉础閻愬秵妫冮崺鈧い鎺戝瀹撲礁鈹戦悩鎻掝伀缁惧彞绮欓弻娑氫沪閹规劕顥濋梺閫炲苯澧伴柟铏崌閿濈偛鈹戠€n€晠鏌嶆潪鎷屽厡闁汇倕鎳愮槐鎾存媴閸撴彃鍓卞銈嗗灦閻熲晛鐣烽妷褉鍋撻敐搴℃灍闁绘挻娲橀妵鍕箛闂堟稐绨肩紓浣藉煐濮樸劎妲愰幘璇茬闁冲搫鍊婚ˇ鏉库攽椤旂》宸ユい顓炲槻閻g兘骞掗幋鏃€鐎婚梺瑙勬儗閸樺€熲叺婵犵數濮烽弫鍛婃叏椤撱垹纾婚柟鍓х帛閳锋垶銇勯幒鍡椾壕缂備礁顦遍弫濠氱嵁閸℃稒鍊烽柛婵嗗椤旀劕鈹戦悜鍥╃У闁告挻鐟︽穱濠囨嚃閳哄啰锛滈梺褰掑亰閸欏骸鈻撳⿰鍫熺厸閻忕偟纭堕崑鎾诲箛娴e憡鍊梺纭呭亹鐞涖儵鍩€椤掑啫鐨洪柡浣圭墪閳规垿鎮欓弶鎴犱桓闂佸湱枪閹芥粎鍒掗弮鍫熷仺缂佸顕抽敃鍌涚厱闁哄洢鍔岄悘鐘绘煕閹般劌浜惧┑锛勫亼閸婃牠宕濋敃鈧…鍧楀焵椤掍胶绠剧€光偓婵犱線鍋楀┑顔硷龚濞咃絿妲愰幒鎳崇喓鎷犻懠鑸垫毐闂傚倷鑳舵灙婵炲鍏樺顐ゆ嫚瀹割喖娈ㄦ繝鐢靛У绾板秹寮查幓鎺濈唵閻犺櫣灏ㄥ銉р偓瑙勬尭濡繂顫忛搹鍦<婵☆垰鎼~宥囩磽娴i鍔嶉柟绋垮暱閻g兘骞嬮敃鈧粻濠氭偣閸パ冪骇鐎规挸绉撮—鍐Χ閸℃ê闉嶇紓浣割儐閸ㄥ墎绮嬪澶嬪€锋い鎺嶇瀵灝鈹戦埥鍡楃仯闁告鍕洸濡わ絽鍟崐鍨叏濡厧浜鹃悗姘炬嫹

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初始化时临时建立的。.
更多精彩
赞助商链接