Biztalk中消息保存在messagebox数据库的spool表和parts表中。SPOOL 表的内容是消息的总体性描述和消息的上下文属性,一条消息在此表中为一条记录。PARTS 表存放多部分消息的各个部分,一个部分在此表中占一条记录。哪一个是正文部分由spool表中的uidBodyPartID标识。
Biztalk保存每一条消息,不管这个消息是否已经不再有用。随着时间推移,消息会不断堆积,占用占用硬盘空间,给系统的性能带来负面影响。所以一般需要定期对messagebox数据库中的消息进行清理,把一些过期的无用的消息清理掉。
Biztalk 2006 提供了消息清理工具,帮助用户日常清理消息。清理消息的依据就是看这条消息是否被服务实例引用,如果这条消息已经不被任何实例引用,说明此条消息已经被使用完毕,在系统中不会再被使用,可以删除。
前一篇文章《深入biztalk消息引用和引用计数》中已经分析了biztalk中消息的引用机制,对此部分不了解的朋友可以参考此文章。
引用计数分为两种情况:
l 一个消息只有一个服务订阅:这种情况十分简单,引用计数保存在本地引用计数表BizTalkServerApplication_MessageRefCountLog中,因为只有一个服务实例使用这个消息,所以这个服务实例完成后直接把这个消息的guid存入MessageZeroSum表中,表示这条消息已可删除。
l 一个消息有多个服务订阅:这种情况比较复杂,把引用计数保存到全局消息引用计数表。清理消息作业大部分的工作就是根据全局消息引用表来计算判断哪些消息不再被引用了。
Biztalk2006中清理消息应该执行MessageBox_Message_ ManageRefCountLog_BizTalkMsgBoxD作业,在这个作业中会调用MessageBox_Message_ Cleanup_BizTalkMsgBoxDb作业,从而一同完成清理消息的任务。
MessageBox_Message_ManageRefCountLog_BizTalkMsgBox只有一个步骤,调用bts_ ManageMessageRefCountLog存储过程,下面消息分析这个存储过程的作用。
1. 清理非活动引用计数表
消息代理把消息引用计数记入到全局消息引用计数表MessageRefCountLog1或者MessageRefCountLog2中。这个过程是逐笔记录下一个消息被引用的次数,和被释放引用的次数的一个流水过程。
Biztalk还有一个全局引用计数汇总表MessageRefCountLogTotals,此表汇总两个全局引用计数表的引用计数。
MessageRefCountLogTotals表结构如下:
uidMessageID ―― 消息guid
snRefCount ―― 引用计数
tnLastTable ―― 最后更新总表的是哪个分表
根据ActiveRefCountLog表tnActiveTable字段,获得当前非活动引用计数表,调用存储过程int_PurgeMessageRefCountLog清理非活动引用计数表。
int_PurgeMessageRefCountLog存储过程的作用:
l 把非活动引用计数表按照消息guid分组汇总每个消息的引用计数
l 把非活动引用计数表的消息计数跟全局引用计数汇总表相同guid的消息的引用计数相加更新到全局引用计数汇总表。
l 把非活动引用计数表中在全局引用计数汇总表中没有的消息计数插入到全局引用计数汇总表。
l 将所有此次汇总表中受影响的记录的tnLastTable设为这个非活动引用计数表的表号。
l 因为非活动引用计数表中的内容已经全部更新到全局引用计数汇总表,全部删除非活动引用计数表的记录。
l 将全局引用计数汇总表中最后更新为活动表号的,引用计数snRefCount为零的消息记录转存到MessageZeroSum表中,同时把这些记录在全局引用计数汇总表中删除。在MessageZeroSum表中的消息就表示是可以删除的了。
2. 交换活动表,再清理当前活动引用计数表
上一步处理了非活动引用计数表,此时非活动引用计数表应该为空。这一步把活动引用计数表和非活动引用计数表作个交换,通过重设ActiveRefCountLog表tnActiveTable字段来完成。这样原来的活动引用计数表就变成了非活动引用计数表,同样调用int_PurgeMessageRefCountLog过程,来清理当前非活动引用计数表。过程同上一步骤一样。
通过这两个步骤,把两个全局引用技术表都进行了处理,同时也把不再被引用的消息从全局引用计数汇总表中删除,转存到了MessageZeroSum表中。MessageZeroSum表中的消息表示是可以删除消息,MessageZeroSum表主要字段就是一个消息的guid。
3. 调用实际清理消息作业
这一步骤调用MessageBox_Message_ Cleanup_BizTalkMsgBoxDb作业,MessageBox_Message_ Cleanup_BizTalkMsgBoxDb作业也只有一个步骤,是调用bts_PurgeMessages存储过程,bts_PurgeMessages存储过程又调用int_PurgeMessageZeroSumTable存储过程。
下面看一下int_PurgeMessageZeroSumTable过程的功能:
l 把spool表中跟MessageZeroSum表相关的消息删除。
l 清空MessageZeroSum表。