ActiveMq - Kaha - Store is locked… waiting 10 seco

2019-07-01 19:32发布

问题:

I have two queues on my application (Spring3-Hibernate-ActiveMq). Thanks for your comments in advance. I would be glad if you help me avoid the following error:

10:02:41,541 INFO KahaStore:463 - Kaha Store using data directory \tmp\kahadb 10:02:41,542 INFO KahaPersistenceAdapter:185 - Store is locked... waiting 10 seconds for the Store to be unlocked. 10:02:51,542 INFO KahaStore:463 - Kaha Store using data directory \tmp\kahadb 10:02:51,543 INFO KahaPersistenceAdapter:185 - Store is locked... waiting 10 seconds for the Store to be unlocked. 10:03:01,543 INFO KahaStore:463 - Kaha Store using data directory \tmp\kahadb .. .

And Here is my applicationContext.xml

<amq:connectionFactory id="amqConnectionFactory"
    brokerURL="vm://localhost" />

<bean id="connectionFactory"
    class="org.springframework.jms.connection.CachingConnectionFactory">
    <constructor-arg ref="amqConnectionFactory" />  
    <property name="sessionCacheSize" value="100" />
</bean>

<bean id="jmsTemplateForProduct" class="org.springframework.jms.core.JmsTemplate"
    p:defaultDestinationName="Click.Queue.Product">
    <constructor-arg ref="connectionFactory" /> 
</bean>

<bean id="jmsTemplateForPayment" class="org.springframework.jms.core.JmsTemplate"
    p:defaultDestinationName="Click.Queue.Payment">
    <constructor-arg ref="connectionFactory" /> 
</bean>

<jms:listener-container concurrency="10">
    <jms:listener id="ProductListener" destination="Click.Queue.Product"
        ref="productListener" />
</jms:listener-container>

<jms:listener-container concurrency="10">
    <jms:listener id="PaymentListener" destination="Click.Queue.Payment"
        ref="paymentListener" />
</jms:listener-container>
<!-- ActiveMQ ends -->

回答1:

Well, I have solved the problem by myself. BTW thanks jkysam for your comments.

The problem was occured because of loading of applicationContext more than once. So, anytime applicationContext is loaded, a new instance of kaha db is created and it results to locking.

What I did is that I seperated jms related configuration from applicationContext. So, I created a new context xml file called jmsContext.xml, and move the jms (and activemq as well) related configuration lines to that file. Then in my test classes, I loaded different context xml's depend on whether it is a jmsTest or not.

For instance; I have two GenericUnitTest class in order to seperate context configuration. First is:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"/jmsContext.xml"})
public abstract class GenericJmsUnitTest {  
}   

Second one is:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"/applicationContext.xml"})
public abstract class GenericUnitTest { 
}   

And then I extend these classes depend on the test case. Here is the example;

public class ProductQueueTest extends GenericJmsUnitTest{  
@Autowired
private ProductQueueService productQueueService;

@Test
    public void productTest() {   
     productQueueService.sendProduct(); 
    }
}

The non-jms test class sample is:

public class SchedularTest extends GenericUnitTest {
    @Autowired
    private Processor schedulerProcessor;

    @Test
     public void scheduleForProduct() {
        schedulerProcessor.processForProducts();
    }
}

BTW, I exclude component scan filters which are about queue in applicationContext.xml, And include them in jmsContext.xml. Here is the example;

applicationContext xml is below

<context:component-scan base-package="com.project">
  <context:exclude-filter type="regex" expression="com.project.queue.*"/>
  <context:exclude-filter type="regex" expression="com.project.test.queue.*"/>
</context:component-scan>

jmsContext xml is below

 <context:component-scan base-package="com.project.queue"/>
 <context:component-scan base-package="com.project.test.queue"/>


回答2:

Kaha is ActiveMQ's persistency store and it has a lock file that prevents multiple AMQ processes from accessing it at the same time. On a clean exit this lock will always be removed but if for any reason the process didn't finish correctly the lock might not be deleted. Also, if you are running multiple brokers they could be defaulting to the same Kaha location, in your case \tmp\kahadb, and one of them wouldn't get to the store. See the Kaha link for a way to reconfigure the location.

If neither one of those scenarios applies to your situation you might have run into a legitimate problem with broker but you need to provide more details about how you get the lock checking code to fail.