2

我有这个过程,在一个表中,我们有一系列项目移动,这些移动将应用于包含项目和库存的另一个表。基本上,项目移动表由以下实体映射:

public class ItemMovement {
    enum ItemMovementStatus { NEW, APPLIED }
    private Long movementId;
    private String itemName;
    private String itemCategory;
    private String arbitraryQualifier;
    private Date movementDate;
    private ItemMovementStatus status;  
    // getters & setters
}

库存项目实体是这样的:

public class InventoryItem {
    private String itemName;
    private Double itemStock;
    private String arbitraryQualifier;
    // getters & setters
}

在一个月的过程中会产生变动,在月末所有变动都必须“应用”到库存表中。“应用”移动基本上意味着从存在完全匹配的库存表的 STOCK 值中减去每个给定移动的 ITEM_MOVEMENT_QTY。如果存在至少与所需移动数量完全匹配的情况,则工作完成。如果没有,我们只取我们能取的,然后继续从另一个属于同一 ITEM_CATEGORY 的项目中取。如果最后一个库存项目没有足够的数量来完成请求的移动数量,我们必须从与移动项目共享相同 ARBITRARY_QUALIFIER 的库存项目中获取。最后一个问题是,这个 ARBITRARY_QUALIFIER 的匹配可以来自数百甚至数千个“匹配” 每个运动项目,因为,顾名思义,这个限定词可以关联两个“完全”不相关的项目。在最坏的情况下(非常糟糕),尽管距离很远,但所有库存物品都应该与给定的物品移动相匹配。

最初我想检索所有匹配项(以块的形式,即查询是“分页的”),如下所示:

select m,i from ItemMovement m, InventoryItem i where 
    m.itemname=i.itemname 
    or m.itemCategory=i.itemCategory 
    or m.arbitraryQualifier=i.arbitraryQualifier

然后以非常面向 OO 的方法处理每个动作及其所有匹配项,但是当有超过 20K 的动作和 20K 库存物品时,这会花费太多时间。我实际上可以看到检索数据的查询(即使分页)花费了太多时间(每页超过一分钟)。花费太多时间本身不是问题,而是禁止我持有交易超过 10 分钟的约束。我知道我可以增加这个值,但我想知道我采用的方法是否正确。我当然希望保持一个非常OO的方法,以便完全控制项目移动的过渡并保持算法非常清晰。我相信这里的“真正”问题是:

¿ OO 是执行这种“类型”过程的正确“方法”吗?如果是这样,是否有一种设计模式可以更好地解决我在性能、代码可维护性方面的问题?¿ 这是一个我应该寻找的过程,例如,PL/SQL 存储过程吗?

我正在使用 EJB、JPA(休眠)。数据库是甲骨文。

谢谢,

4

1 回答 1

1

hibernate 不是为批处理操作而设计的。与使用 hibernate 相比,使用 PL/SQL 过程可以获得更好的性能。

在决定是使用 java 还是使用 PL/SQL 时,您必须考虑整个系统架构。在大多数情况下,使用休眠可以为批处理作业获得足够的性能。

无论您选择什么,通常都有一些方法可以提高给定架构内的性能。

使用 hibernate 需要考虑的一件非常重要的事情是您如何访问您的对象。您希望使用少量SELECT操作从数据库加载对象。SELECT如果您使用 2 (每个对象类型一个)加载所有对象,您的工作很可能会比使用 20000(每个移动一个)更快。

于 2013-04-15T15:20:42.687 回答