多用户并发访问导致的错误

时间:2022-08-29 11:35:14
2015年最后一个晚上聚会22:00多回到家,发现与客户交流群中满当当的一堆消息,客户反馈二手车系统照片不显示了。重启 Tomcat 之后问题解决,但是没有找到导致问题的原因。

元旦早上客户又反馈有一辆车的认证报告和检测证书数据不一致,看来这个元旦注定要在加班中度过了。

检查发现检测证书是另外一辆车的数据。从服务器把系统日志取下来,发现是两台微机同时审核数据生成检测证书PDF文件的时候出错的。日志如下:

[INFO ] 2015-12-31 11:52:42,380       com.action.ActReportCheck     - carNetID:0000920998
[INFO ] 2015-12-31 11:52:42,397       com.action.ActReportCheck     - carNetID:0000898444
[INFO ] 2015-12-31 11:52:43,070 com.report.service.SrvReport_jczs     - 开始生成检测证书pdf...
[INFO ] 2015-12-31 11:52:43,083 com.report.service.SrvReport_jczs     - 二维码: http://xxx.xxx.xxx.xxx/xxx/authReport/authReportIndexNoIIOrange.jsp?tid=15123131070325520002&isShowPrint=F
[INFO ] 2015-12-31 11:52:43,097 com.report.service.SrvReport_jczs     - /mnt/tomcat8.0/webapps/xxx/reportSource/jczs.jasper
[INFO ] 2015-12-31 11:52:43,097 com.report.service.SrvReport_jczs     - 报表JsonData:{"total":"1","rows":[{"bjtp":"/mnt/tomcat8.0/webapps/xxx/WEB-INF/classes/com/source/jczs_bg.jpg","brand":"荣威","companyName":"xxx公司","country":"中国","displayCardNo":"0000920998","factory":"汽车","inspectDate":"2015-12-31","inspectGrade":"/mnt/tomcat8.0/webapps/xxx/WEB-INF/classes/com/source/star40.png","productionDate":"2010-10-01","qrCode":"/mnt/tomcat8.0/webapps/xxx/download/report/jczs/2015/12/31/15123131070325520002.jpg","registerDate":"2011-03-24","showMileage":"87320公里","vin":"LSJA16E30AG049374"}]}
[INFO ] 2015-12-31 11:52:43,097 SrvReport_jczs     - 开始打印...
[INFO ] 2015-12-31 11:52:43,099 com.report.service.SrvReport_jczs     - 开始生成检测证书pdf...
[WARN ] 2015-12-31 11:52:43,105 net.sf.jasperreports.engine.fonts.FontUtil     - Font '宋体' is not available to the JVM. For more details, see http://jasperreports.sourceforge.net/api/net/sf/jasperreports/engine/util/JRFontNotFoundException.html
[INFO ] 2015-12-31 11:52:43,112 com.report.service.SrvReport_jczs     - 二维码: http://xxx.xxx.xxx.xxx/xxx/authReport/authReportIndexNoIIOrange.jsp?tid=15123131070383050013&isShowPrint=F
[INFO ] 2015-12-31 11:52:43,127 com.report.service.SrvReport_jczs     - /mnt/tomcat8.0/webapps/xxx/reportSource/jczs.jasper
[INFO ] 2015-12-31 11:52:43,127 com.report.service.SrvReport_jczs     - 报表JsonData:{"total":"1","rows":[{"bjtp":"/mnt/tomcat8.0/webapps/xxx/WEB-INF/classes/com//source/jczs_bg.jpg","brand":"荣威","companyName":"xxx公司","country":"中国","displayCardNo":"0000898444","factory":"汽车","inspectDate":"2015-12-31","inspectGrade":"/mnt/tomcat8.0/webapps/xxx/WEB-INF/classes/com/source/star45.png","productionDate":"2012-09-01","qrCode":"/mnt/tomcat8.0/webapps/xxx/download/report/jczs/2015/12/31/15123131070383050013.jpg","registerDate":"2013-02-23","showMileage":"61404公里","vin":"LSJB36W95CS076099"}]}
[INFO ] 2015-12-31 11:52:43,127 com.report.service.SrvReport_jczs     - 开始打印...
[WARN ] 2015-12-31 11:52:43,132 net.sf.jasperreports.engine.fonts.FontUtil     - Font '宋体' is not available to the JVM. For more details, see http://jasperreports.sourceforge.net/api/net/sf/jasperreports/engine/util/JRFontNotFoundException.html
[INFO ] 2015-12-31 11:52:43,169 com.report.service.SrvReport_jczs     - download/report/jczs/2015/12/31/15123131070383050013.pdf
[INFO ] 2015-12-31 11:52:43,194 com.report.service.SrvReport_jczs     - PDF文件路径:download/report/jczs/2015/12/31/15123131070383050013.pdf
[INFO ] 2015-12-31 11:52:43,212 com.report.service.SrvReport_jczs     - download/report/jczs/2015/12/31/15123131070383050013.pdf
[INFO ] 2015-12-31 11:52:43,223 com.report.service.SrvReport_jczs     - PDF文件路径:download/report/jczs/2015/12/31/15123131070383050013.pdf
[INFO ] 2015-12-31 11:52:43,227 com.report.service.SrvReport_jczs     - 更新 PDF 文件路径成功!
[INFO ] 2015-12-31 11:52:43,242 com.report.service.SrvReport_jczs     - 更新 PDF 文件路径成功!
[INFO ] 2015-12-31 11:52:43,262        com.netImpl.NetCarDetail     - 上传评估报告 展示证:0000920998 地址: http://xxx.xxx.xxx.xxx:80/xxx/authReport/authReportIndexNoIIOrange.jsp?tid=15123131070325520002
[INFO ] 2015-12-31 11:52:43,287        com.netImpl.NetCarDetail     - 上传评估报告 展示证:0000898444 地址:http://xxx.xxx.xxx.xxx:80/xxx/authReport/authReportIndexNoIIOrange.jsp?tid=15123131070383050013

 

源代码是这样的:

/**
* 打印检测证书,导成PDF文件
* @author SunJing
*/
@Component("srvReport_jczs")
public class SrvReport_jczs {
… …

}

 

@Component("srv_printReport")
public class Srv_printReport {

static private Logger logger = LoggerFactory.getLogger(Srv_printReport.class);
private String jsonData;
private String fileName;
private String isPrint; // 是否直接打印 T F
private String reportSource;
private String filePath;
private SrvBaseTable srvBaseTable;

@Value("${systemSet.projectPath}")
private String projectPath;

… …

// 生成PDF文件

public String exportPDFReport() throws Exception {
logger.info("Srv_printReport 对象标识:" + this.hashCode());

… …

}

}

SrvReport_jczs 调用 Srv_printReport 生成检测证书PDF文件。

 

错误原因:检测报告与实际数据不一致原因为生成检测报告时Spring框架注入了同一个 Srv_printReport 对象,当两个客户同时审核报告时,Srv_printReport 对象所用的报告内容都是通过setXXX()函数赋值的,第一份报告还没生成,第二份报告把第一份报告的内容覆盖了。

解决方法:1、通过重新new一个对象来解决这个问题;2、Srv_printReport 的报告内容不要定义成类成员变量,直接在exportPDFReport()函数内定义临时变量,通过参数的形式传入。

2016-01-05

今天测试了一下,ActReportCheck(Action类)、SrvReport_jczs、Srv_printReport三个类全部使用注解@Scope(“prototype”),Action类调用SrvReport_jczs、SrvReport_jczs调用Srv_printReport,使用Spring框架注入的方式调用,每次调用时重新注入一个Srv_printReport对象。OK,成功解决问题。^_^
原先导致错误的原因为SrvReport_jczs没有使用注解@Scope(“prototype”),所以每个action实例访问的都是用一个SrvReport_jczs对象,所以SrvReport_jczs调用的也是同一个Srv_printReport对象。