Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JMS消息驱动bean-如何同步线程?_Java_Multithreading_Jpa_Jms - Fatal编程技术网

Java JMS消息驱动bean-如何同步线程?

Java JMS消息驱动bean-如何同步线程?,java,multithreading,jpa,jms,Java,Multithreading,Jpa,Jms,尽管messagedriven bean基于异步逻辑,但我有以下场景: 2个包含用户凭据的领域(jdbc和ldap) 当用户在表单中输入用户名和密码时,它会尝试在两个领域(jdbc和ldap)中进行自动验证 对于每个尝试登录的领域,我都会发送一条带有JMS的消息来记录它 我的问题在于onMessage(Message Message)重写的方法 考虑以下JMS消息Bean的Java伪代码: public void onMessage(Message message){ String us

尽管messagedriven bean基于异步逻辑,但我有以下场景:

  • 2个包含用户凭据的领域(jdbc和ldap)
  • 当用户在表单中输入用户名和密码时,它会尝试在两个领域(jdbc和ldap)中进行自动验证
  • 对于每个尝试登录的领域,我都会发送一条带有JMS的消息来记录它
  • 我的问题在于onMessage(Message Message)重写的方法

    考虑以下JMS消息Bean的Java伪代码:

    public void onMessage(Message message){
        String username = (cast message to Map and get username);
        Login login = (Login)loginDAO.filter( queryByUsername, username );
        if( login == null ){
            Creates a new entry at database for 'username'
        }else{
            Uses 'username' already created
        }
    }
    
    现在我的问题是:

  • 我在表单中输入用户名和密码,然后按Login
  • 尝试在JDBC上登录并触发JMS来记录它
  • 尝试在LDAP上登录并激发JMS来记录它
  • onMessage几乎同时接收2条消息(项目2和3)
  • 消息1创建了一个新用户,因为它在数据库中不存在
  • 消息2还创建了一个具有相同用户名的新用户
  • 我需要消息2在消息1(if-logic)上使用创建的用户(else-logic),但我认为它(消息2)太快了,以至于条目还没有在DB中持久化,两条消息都在“if-logic”中捕获

    如果我的主题混淆且不恰当,请给出建议

    [编辑]到目前为止,我得到的是:

    服务器中有一个MessageDrivenBean(MDB)池,对于到达的2条消息,您将同时运行2个MDB,因此您将保留相同的信息2次

    我在注释消息驱动Bean中使用了一个名为maxSession的属性

    @ActivationConfigProperty(propertyName = "maxSession", propertyValue = "1")
    
    现在池中只有一个MDB,我在负责检查“username”登录审核的所有逻辑的方法中放置了一个SYNCHRONIZED

    [编辑2]根据Nicholas的观察,如下所示:

    删除了池限制,我为数据库检查创建了一个静态方法(检查用户名是否存在或是否需要创建和持久化)

    静态,因为它需要和MDB的所有实例共享,并且还需要同步以避免在数据库中重复条目


    谢谢

    在不知道这段代码实际应该做什么的情况下,MDB似乎仍然是实现同步的错误位置。假设您将拥有有限数量的用户,并且每个用户将处理多条消息。通过将MDB池限制为一个实例,您严重限制了MDB处理器上的吞吐量

    与其尝试在MDB中进行同步,我建议您考虑在用户名持久化机制中实现同步,或者如您在代码中所述:

    Creates a new entry at database for 'username'
    

    通过这种方式,可以同时处理多条消息,但是当fortune决定哪个线程保存用户名时,它们会短暂地阻塞(一个线程保存用户名,然后获取用户名,其他线程等待用户名,然后获取用户名)。在此之后,您将不会多次阻止单个用户名,您可以运行一个完整的MDB池。

    您的数据库是否没有存储用户详细信息的表的PK?第二个insert肯定会抛出异常。是的,它抛出了异常。我使用的是JPA,所以hibernate会在persistentEntityManager中增加ID