Java JMS消息驱动bean-如何同步线程?
尽管messagedriven 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
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
}
}
现在我的问题是:
@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