我不知道在我的服务类上使用什么注释来最小化应用程序所需的内存。
以一个客户/订单场景为例,我想找到单个客户的最大总支出。总共有100万个订单和100个客户,每个客户下了10,000个订单。
我能想到的最简单的例子是:
public class MyService {
@Transactional(readOnly=true)
public int getMaxSpend() {
int maxSpend = 0;
List<Customer> customers = customerDao.findAll();
for(Customer customer : customers) {
List<Order> orders = orderDao.getOrders(customer);
for(Order order : orders) {
if(order.getTotal() > maxSpend) maxSpend = order.getTotal();
}
}
return maxSpend;
}
}
由于交易跨越了每个客户订单的加载,我相信休眠会话中最终会有一百万个对象,这远非理想。Order
一旦为该客户完成迭代,我想通过垃圾收集每个客户的订单来最小化内存中的实例数量。
在以下示例中,客户没有引用他们的订单集合,也没有订单引用他们的客户:
public class MyService {
@Transactional(propagation=Propagation.NEVER)
public int getMaxSpend() {
int maxSpend = 0;
List<Customer> customers = getAllCustomers();
for(Customer customer : customers) {
int customerSpend = getCustomerSpend(customer);
if(customerSpend > maxSpend) maxSpend = customerSpend;
}
return maxSpend;
}
@Transactional(readOnly=true)
private List<Customer> getAllCustomers() {
return customerDao.findAll();
}
@Transactional(readOnly=true)
private int getCustomerSpend(Customer customer) {
int customerSpend = 0;
List<Order> orders = orderDao.getOrders(customer);
for(Order order : orders) {
customerSpend += order.getTotal();
}
return customerSpend;
}
}
不幸的是,当我在 jprofiler 中分析内存时,仍然有 100 万个Order
加载实例。我期待一个休眠异常,因为我认为私有方法不能是事务性的,但这从未发生过。以上是正确的方法,我已经以某种方式打开了交易,还是有不同的方法来实现我的目标?