您的位置:首页 > 数据库

数据同步案例分析

2012-03-17 09:39 169 查看
项目:某物流公司物品定价管理

背景:(定价灌档)读取excel数据,实现入库操作,需要在5分钟以内处理完并反馈结果

前提:对于每次定价灌档,需遵循事物的原子性(对数据库的操作要么全部执行,要么完全不执行),灌档Excel数据量在0~10000之间,对于每条数据进行以下业务逻辑

1) 查询料品表获取捕获代码;

2) 查询公司表获得税率;

3) 查询定价表判断该数据是否存在,存在则update,否则insert;

然后查询定价表判断地区*(即根据地区CN,HK,AU分别额外增加的记录分别为:***,HK*,AU*)数据记录是否存在,存在则update,否则insert;

4) 在company处于澳洲的情况下,需增加/更新特约价(ZZ,ZY)记录,及AU*下的(ZZ,ZY)记录;

5) 统一更新建议零售价

初始方法按正常逻辑编写代码:循环处理每条记录信息

问题:超过4000笔记录,时间超时,页面无反馈结果,后台异常抛出weblogic服务超时

问题原因:根据以上的定价灌档业务逻辑分析

l 最好的情况下:灌档数据量为8000条,地区处于CN,即需查询8000次、insert(或update)记录8000次,update零售价20*8000次,最后一次性commit,时间超过半个小时

l 最坏的情况下:灌档数据量为8000条,地区处于AU,即需查询40000次、insert(或update)记录50000次,update零售价25*8000次,最后一次性commit,时间超过1小时

初始解决方案:

1) 设置<prop key="hibernate.jdbc.batch_size">50</prop>,

通过Session来进行批量操作:

Session的save()及update()方法都会把处理的对象存放在自己的缓存中,处理通过一个Session对象来处理大量持久化对象,应该及时的从缓存中清空已经处理完毕并且不在访问的对象,具体的做法是在处理完一个对象或者小批量后,立刻调用flush()方法清理缓存,然后调用clear()方法清空缓存。

Session session = Sessionfactory.openSession();

Transaction tx = session.beginTransaction();

for(int = 0; i <100000;i++){

Entity entity= new Entity(....);

session.save(entity);//或者在此处更新

if( i % 50 == 0){//单次批量操作数量为50

session.flush(); //清理缓存,执行批量插入50条记录的SQL insert语句

session.clear();//清空缓存中的Entity对象

}

}

tx.commit();

session.close();

2) 修改建议零售价的Hibernate方式改为JDBC的批量操作方式

但是发现这个方案,效果不是很明显,达不到客户需要的需求(5分钟内响应)

最终解决方案:

1) 采用临时表与定价表实现数据同步,同样的操作1分钟内完成

具体步骤:

在灌档之前先将所有的Excel数据保存到临时表table1中(注:此步是在确认灌档前的另一功能完成),然后点击确认灌档执行以下的6次A语句和6次B语句以达到修改table2中产品定价的目的

A:Insert intotable1 select column1, column2... from table2 where...

B:Updatetable1 a set (a.column1, a.column2...) = (select b.column1, b.column2... fromtable2 b where ...) where...

分析:采用优化方案直接在数据库中实现两表的操作,省去了hibernate与数据库的交互过程、读取内存时间、读取硬盘数据时间等,从而达到效率优化。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息