如何使用数据库实现完美的队列

时间:2014-12-22 18:53:11

标签: java database-design architecture

我正在设计购物车,
我的购物车中有X个产品。 每个产品都与商店相关联。

  • 示例产品1由Shop1
  • 出售
  • 示例产品2由Shop2
  • 出售
  • 示例产品3由Shop3
  • 出售
  • 示例产品4由Shop4
  • 出售

  1. 我以XML的形式获得了Product1的详细信息(Shop1中的可用性和价格[当产品销售或价格发生变化时])
  2. 我应该在购物车中更新这些详细信息。
  3. 应如何处理?

    我将项目分为两部分:

    1:项目1

    我创建了一个基于表单的应用程序,所有商店都使用它 当产品售出时,店铺管理员将输入产品详细信息(可用单位数量等)并提交。我将其转换为XML并保存到Table1。

    例:
    表1

    Product_ID  | XML 
    --------------------------------
    Prod_1A     | xml  
    Prod_2A     | xml  
    Prod_3A     | xml  
    Prod_1A     | xml  
    

    2:项目2

    在这个项目中,我使用了

    ServletContextListener
    

    ServletContextListener contextInitialized方法的帮助下,部署此项目时 我正在创建一个Timer,每10秒运行一次。在那Timer我正在检查 Table1 是否包含任何记录。如果是,在Timer类的run方法中,我从中选择1条记录并更新购物车中的数据。

    for (int i = 0; i <= 5 ; i++) {
    
        fetchFromNotif = fetchFromNotif(); // this methods picks a unique record
        if (fetchFromNotif != null) {
            new Thread()
            {
                public void run()
                {
                    // updating the data in my Shopping cart DB.
                }
            };
            t.start();
        }
    }
    

    我的问题是,这是否是每10秒使用Timer并创建多个线程的正确方法?有没有更好的方法来实现这些要求。

    是否有更好的方法为这种情况实现队列机制?

3 个答案:

答案 0 :(得分:3)

您可以使用JMS。

- 您将在服务器上运行JMS服务(可以是部署项目2的同一服务器)

-Project 1-将XML添加到队列

- 项目2-将从队列中读取。

使用JMS,您不必实现自己的计时器/监听器。 项目1将获得与队列的连接,并将消息添加到队列。 JMS客户端将实现MessageListener。每当项目1将消息添加到队列时,将调用项目2中的MessageListener#onMessage

要创建队列,您可以使用Apache's ActiveMQ

同时检查: how-can-i-use-textmessage-to-send-an-xml-file-to-the-jms-queue

编辑:正如'Amrola'所指出的,使用MDB(消息驱动Bean)比使用Message Listener更好。使用MDB将为您提供ejb容器提供的服务。

答案 1 :(得分:2)

您还可以确定购物车中所需的更新产品信息的确切情况,并提取信息而不是推送信息。也许你不需要实时更新它?

也许您可以检查产品库存或价格的任何更新是否仅在用户进入结账时发生?或者也许在其他方面你确定......

这样你可以简化事情而不用担心线程或队列。

答案 2 :(得分:2)

我清楚地了解到,您需要从 Project#2 中轮询 Project#1 模块数据库以获取产品更新并更改数据库中的购物卡数据#2

没有详细说明,在 Project#2 中,您可以实现ScheduledExecutorService并在其中进行获取和更新:

public class MyAppServletContextListener 
           implements ServletContextListener {
. . .
    @Override
    public void contextInitialized(ServletContextEvent e) {
        //Schedule cart updater

        Executors.newSingleThreadScheduledExecutor()
            .schedule(new Runnable() {
                @Override
                public void run() {
                    ProductUpdate productUpdate = fetchProductUpdate();

                    //do some additional stuff with productUpdate, some checks or logging

                    updateShoppingCart(shoppingCart, productUpdate);
                }
            }, 10, TimeUnit.SECONDS);
    }

}

但实际上,如果不强烈要求将产品更新逻辑与购物车更新分开,我建议在商店更新产品后立即更新 Project#1 中的所有购物车数据。 那么您不需要任何计时器,因为您已经在产品更新上下文中,并且您可以确切地看到哪个产品已更新以及哪些数据已更改。

public void processProductUpdateForm(ProductUpdate upd) {
    updateProductInDatabase(upd);


    updateAssociatedShoppingCarts(upd);

}