1/9用友股份-LE支持服务业务本部技术方案--《NC56固定资产审批报错问题》建立日期:2013-10-20修改日期:xxxx-xx-xx文档属性:客户文控编号:LE-DY-JS-2013-01312/9文档控制创建记录适用范围审阅人日期审阅签字所属部门发布范围发布人姓名所属部门发布时间内部员工伙伴客户日期作者所属部门邮件地址版本2013-10-20魏享林技术支持部V1.0版本领域模块备注NC56集团财务固定资产3/9目录NC56固定资产审批报错问题..................................................................................4一、系统环境............................................................................................................4二、问题描述............................................................................................................4三、检查分析............................................................................................................4四、解决方法............................................................................................................94/9NC56固定资产审批报错问题一、系统环境NC版本:NC56操作系统:Linux中间件:was单机二、问题描述顾问反映月底固定资产审批时报错,一个月出现一次,不重启中间件就会一直报错,用NC中间件无此问题。三、检查分析1、查看后台日志,发现是一个事务中访问多个数据源导致的错误报错信息如下5/9从报错信息看出,固定资产审批时,固定资产模块的一个VO需要克隆,克隆时需要调用基本档案缓存得到某一档案项名称信息,基本档案缓存从数据库加载数据时,报了一个事务访问多个数据源错误。2、从程序看,看不出会访问到不是当前帐套的数据源,怀疑是别的问题,为此在NC中输出数据源信息,看访问到了哪个数据源3、补丁打到用户环境后,在下次问题出现时,找到输出的日志对应的打桩日志输出如下,可以看到,在加载基本档案数据时,访问到的数据源为nc52to57,而不是nc57,确认问题出在程序找错数据源上。6/9询问用户能否把nc52to57数据源删除,用户反映这个帐套还有用,无法删除。4、在InvocationProxy的设置当前数据源方法中,输出调试信息,看是哪个方法将当前数据源设错了。5.补丁再次打到用户环境中,并检查打桩日志7/9可以看出,就是加载基本档案缓存的方法将当前数据源设置成了nc52tonc57。6.依照设置错了当前数据源的线程堆栈,逐步分析代码,找到了出错代码,出具补丁,补丁在用户环境下测试通过UAP为访问基本档案数据提供了AccessorManager类,该实现是支持多数据源的,而固定资产中,又做了个AssAccessorManager,在该类中,对于各档案的Accessor做了缓存,但是在这种实现又没有考虑支持多数据源。实际上UAP的AccessorManager已经对各档案的Accessor做了缓存,所以AssAccessorManager这个类根本没有存在必要。8/9补丁打到用户环境后,经过几个月的测试,没有发现问题。7.问题分析出现这个问题的原因是,如果AssAccessorManager加载某一类型档案时,第一次加载的是nc52tonc57,则在nc57数据源对应的帐套下做固定资产审批时,如果需要加载基本档案,则又会去访问nc52tonc57数据源,导致出现一个事务访问多个数据源的错误。这个项目的这个错误只出现在was中间件,而不出现在NC中间件下的原因是:was对于一个事务访问多个数据源的校验很严格,也很规范,而NC中间件不是很规范,如果访问的第二个数据源不涉及到事务,即只是查询操作,则不会报错,这个项目中,访问nc52tonc57数据源只是去加载基本档案数据,不涉及到修改,所以在NC中间件下不报错。9/9四、解决方法固定资产对于基本档案缓存的管理缺少对多数据源支持导致,打补丁解决问题。补丁为:nchome.rar,打此补丁不需要部署EJB,重启中间件即可。