I'm seeing some unique constraint violations during a load test of 10,000 messages (only 8 out of 10,000 affected). I'm wondering if it's something I need to change in the DBCP data source settings, or Active MQ settings. The error is
org.springframework.jms.UncategorizedJmsException: Uncategorized exception occured during
JMS processing; nested exception is javax.jms.JMSException:
ORA-00001: unique constraint (WEBSVC.SYS_C00181594) violated
I've looked up this Constraint and tracked it to ACTIVEMQ_MSGS a table we let Active MQ create and maintain itself in Oracle. e.g.
select * from all_constraints
where constraint_name = 'SYS_C00181594'
OWNER CONSTRAINT_NAME CONSTRAINT_TYPE TABLE_NAME SEARCH_CONDITION R_OWNER R_CONSTRAINT_NAME DELETE_RULE STATUS DEFERRABLE DEFERRED VALIDATED GENERATED BAD RELY LAST_CHANGE INDEX_OWNER INDEX_NAME INVALID VIEW_RELATED
------ --------------- --------------- ------------- ---------------- ------- ----------------- ----------- ------- -------------- --------- --------- -------------- --- ---- -------------------- ----------- ------------- ------- ------------
WEBSVC SYS_C00181594 P ACTIVEMQ_MSGS ENABLED NOT DEFERRABLE IMMEDIATE VALIDATED GENERATED NAME 22-Mar-2013 16:16:22 SYS_C00181594
This is happening when I'm placing messages on the queue, full stack trace follows
Caused by: java.io.IOException: ORA-00001: unique constraint (WEBSVC.SYS_C00181594) violated
at org.apache.activemq.util.IOExceptionSupport.create(IOExceptionSupport.java:45)
at org.apache.activemq.store.jdbc.TransactionContext.close(TransactionContext.java:138)
at org.apache.activemq.store.jdbc.JDBCMessageStore.addMessage(JDBCMessageStore.java:129)
at org.apache.activemq.store.memory.MemoryTransactionStore.addMessage(MemoryTransactionStore.java:328)
at org.apache.activemq.store.memory.MemoryTransactionStore$1.asyncAddQueueMessage(MemoryTransactionStore.java:155)
at org.apache.activemq.broker.region.Queue.doMessageSend(Queue.java:744)
at org.apache.activemq.broker.region.Queue.send(Queue.java:717)
at org.apache.activemq.broker.region.AbstractRegion.send(AbstractRegion.java:407)
at org.apache.activemq.broker.region.RegionBroker.send(RegionBroker.java:503)
at org.apache.activemq.broker.jmx.ManagedRegionBroker.send(ManagedRegionBroker.java:311)
at org.apache.activemq.broker.BrokerFilter.send(BrokerFilter.java:129)
at org.apache.activemq.broker.CompositeDestinationBroker.send(CompositeDestinationBroker.java:96)
at org.apache.activemq.broker.TransactionBroker.send(TransactionBroker.java:317)
at org.apache.activemq.broker.MutableBrokerFilter.send(MutableBrokerFilter.java:135)
at org.apache.activemq.broker.TransportConnection.processMessage(TransportConnection.java:450)
at org.apache.activemq.command.ActiveMQMessage.visit(ActiveMQMessage.java:680)
at org.apache.activemq.broker.TransportConnection.service(TransportConnection.java:294)
at org.apache.activemq.broker.TransportConnection$1.onCommand(TransportConnection.java:152)
at org.apache.activemq.transport.ResponseCorrelator.onCommand(ResponseCorrelator.java:116)
at org.apache.activemq.transport.MutexTransport.onCommand(MutexTransport.java:50)
at org.apache.activemq.transport.vm.VMTransport.iterate(VMTransport.java:241)
at org.apache.activemq.thread.PooledTaskRunner.runTask(PooledTaskRunner.java:129)
at org.apache.activemq.thread.PooledTaskRunner$1.run(PooledTaskRunner.java:47)
... 3 more
Caused by: java.sql.BatchUpdateException: ORA-00001: unique constraint (WEBSVC.SYS_C00181594) violated
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10345)
at oracle.jdbc.driver.OracleStatementWrapper.executeBatch(OracleStatementWrapper.java:230)
at org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297)
at org.apache.commons.dbcp.DelegatingStatement.executeBatch(DelegatingStatement.java:297)
at org.apache.activemq.store.jdbc.TransactionContext.executeBatch(TransactionContext.java:103)
at org.apache.activemq.store.jdbc.TransactionContext.executeBatch(TransactionContext.java:81)
at org.apache.activemq.store.jdbc.TransactionContext.close(TransactionContext.java:129)
I have a pretty paranoid DBCP BasicDataSource at the moment i.e.
<bean id="basicOracleDataSource" class="org.apache.commons.dbcp.BasicDataSource"
abstract="true" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.OracleDriver" />
<property name="poolPreparedStatements" value="true"/>
<property name="initialSize" value="5"/>
<property name="maxActive" value="30"/>
<property name="maxWait" value="60000"/> <!-- default indefinitely -->
<property name="timeBetweenEvictionRunsMillis" value="30000" />
<!-- verify connections in the pool to stop connection closed errors -->
<property name="logAbandoned" value="false"/> <!-- default false -->
<property name="maxIdle" value="5"/> <!-- default 8, minIdle defaults to 0 which is OK -->
<property name="numTestsPerEvictionRun" value="4"/> <!-- default 3 -->
<property name="removeAbandoned" value="true"/> <!-- default false -->
<property name="removeAbandonedTimeout" value="60"/><!-- default 300 seconds -->
<property name="testOnBorrow" value="true"/> <!-- default false -->
<property name="testOnReturn" value="true"/> <!-- default false -->
<property name="testWhileIdle" value="true"/> <!-- default false -->
<property name="validationQuery" value="SELECT 1 FROM dual"/>
</bean>
And just in case, here is my JMS Template too
<!-- Spring JMS Template -->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory">
<!-- lets wrap in a pool to avoid creating a connection per send -->
<bean class="org.springframework.jms.connection.SingleConnectionFactory">
<property name="targetConnectionFactory">
<ref local="jmsFactory" />
</property>
</bean>
</property>
</bean>