并发使用definebean读报表

读取报表方式目前提供了两种形式file和definebean两种方法。file形式比较形象化易于理解,在demo中的showreport.jsp用的就是该方法。definebean的方式是通过读取缓存来得到报表的。在咱们帮助文档中做的如下介绍:

<%   String reportPath = request.getRealPath(”/reportFiles/api/wangge.raq”);//取得报表真实路径

ReportDefine rd = (ReportDefine)ReportUtils.read(reportPath);

  request.setAttribute(”reportDefine”,rd); //把ReportDefine对象在request中保存

%>

<report:html name=”report1″

  srcType=”defineBean”

  beanName=”reportDefine”

  exceptionPage=”/jsp/myError.jsp”  //错误提示页面

    />

这里的报表真是路径也可以通过直接从数据库中取到放在session中,直接将raq转成ReportDefine类型

(ReportDefine) request.getSession().getAttribute(”raq”);

当把ReportDefine对象放在request中保存时,定义一个beanName,如果此报表没有出现并发操作时,没有问题,一旦并发操作,这个beanName写死的话,缓存中将会被后访问的definebean替换,从而导致会出先数组越界的报错,控制台中直接显示的是在该生成HTML时报的错并没有打印sql语句。

分析原因:由于采取的是读缓存的方式来展现报表,假如A和B两张报表,同时展现出来,B比A在后台中稍微慢些,这时缓存中由于beanName相同,A的被B替换,也就是说缓存中只有B报表的缓存,这时同时对AB进行填报操作,当A提交时对应的更新属性字段取得是缓存中B报表的,这时会导致数组越界现象,也会出现填报错位,可见是读的另一张报表的缓存按这张报表展现的从而出错。

解决方法:将beanName写活,可以采取用随机数或者用System.currentTimeMillis()去时间当name等方法都可以避免beanName重复。

另外如果beanName写死的话,想通过每次清楚缓存来解决也是不可取的,这事如果在每次展现报表钱执行CacheManager.getInstance().deleteAllReport();或者其他清除缓存的操作,会导致读报表都会读到第一张报表。

你可能感兴趣的:(File,的,咱们)