Java引用陷阱之数据重复保存问题解决小记

      问题提出:昨天在稽核数据时候发现主表和明细数据不一致,查看原始数据表发现同样存在主表和明细表数据不一致,明细表明显存在重复数据,分析重复数据,一条主表记录居然最多对应90条除了主键不一样其他全部相同的明细记录,最少的也有3条明细记录。

 

     问题解决过程:

     数据保存的接口是我提供的,业务开发的同事已经不在,只好自己去找问题根源了。

 

    1,首先确认问题是否存在。

    项目上线很久了,该业务一直运行良好,没有报障,所以我开始认为是统计有问题,再三在生产数据库确认,数据重复问题确实存在,不是统计的问题。

 

    2,找到代码位置,分析代码。

    首先得找到业务对应的代码的位置,原来业务不是我开发的,漫无目的的搜索毫无用处,只好反推,从我的数据保存接口往上,Ctrl+Alt+H,出来一堆的方法调用,一看傻眼了,到底那个出问题了。

   

     昨天下午4点开始到下班,看代码,结果很苦逼,代码不是自己写的,看起来老是怪怪的,怎么看都看不出问题,加上代码中的方法一个比一个长,一个方法从开始到结束大部分长度在600行左右,把我看晕了。

  

    今天上午继续看代码,实话实说,我没看出问题,都看晕了,唯一看出的是代码中没有重复保存问题存在。

   

    3,从页面上找到原始方法调用

    代码没看出问题,只好在页面上把业务一个一个尝试,之所以没有一开始就从页面上点击,是因为我对业务怎么操作的不清楚,现在只剩下这种方法了,不清楚业务怎么操作的,只好请教测试人员询问业务操作流程,被测试鄙视了。

 

     在页面上造了一笔测试数据,点击提交,查看url方法找到调用的原始方法名称,定位代码位置,第一次没有打断点,查看数据库,数据正常,没有重复数据。

 

     换一种业务操作,试下批量操作,第一次只提交了一条记录,马上找到了方法名称,在方法上打算断点,debug运行,批量操作提交只提交1条记录,debug发现情况正常。

 

     难道不是这个业务,不应该,就这2种操作,再测试下,这次批量提交2条测试记录,运行后没看出问题,查看数据库一看,数据库居然不止2条记录,看来就是这个业务出问题了。

 

   4,修改代码

    原始方法找到了,保存方法经测试没有问题,问题在上面,把保存方法里面的内容注释掉,再次debug,发现了一些端倪。

    1,第1条记录时候没有问题。

    2,第2条记录保存前居然能看到第一条记录的数据。

    初步怀疑是引用引起的。原始代码简化后如下:

   

List<ThirdJavaBean> orderItemList = new ArrayList<ThirdJavaBean>();
for(int i=0;i<list.size();i++)
{
   ThirdJavaBean ob=new ThirdJavaBean();
   ob.setXXX();
   orderItemList.add(ob);
   ThirdJavaBean[] tbs=new ThirdJavaBean[orderItemList.size()];
   for(int j=0;j<orderItemList.size();j++)
   {
      tbs[j]=orderItemList.get(j);
   }
   XXSV.saveJavaBean(tbs);
}

   

    -----上面for循环是j<orderItemList.size();自己手写的代码,写成了i,谢谢指正。

 

    不要问我代码为什么这么写,这不是我写的,眼尖的朋友也行发现了问题所在,第4行附近orderItemList 出问题了,由于对象引用,每次循环,下一次时候都能拿到上一次的数据,这是一个由于粗心引起的非常隐蔽的错误。

 

    解决方法如下:

    每次for循环里面都重新new 一个orderItemList,这样就不会出现上面的问题了。

   

    结论:

    1,对象在使用=赋值时候,小心原始对象的引用问题,最好每次重新new一个对象。

    2,论熟悉业务的重要性。

    3,错误很低级,发现不容易。

   

 

   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值