I have spring batch which reads from ActiveMQ Artemis and write to Oracle database. Now I want to implement a mechanism to cater if any SQLException occured in JDBC batch write like following,
org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL
I tried with SkipPolicy and CompositeStepExecutionListener but it seems methods not get called on error. My target is to write the error prone message to a error queue or logs. Is there a way I can do it without extending JdbcBatchItemWriter. Also I want to know your opinion on whether my error handing is efficient?
My target is to write the error prone message to a error queue or logs
ItemWriteListener#onWriteError should be called on write failures. It gives you access to the items of the failed chunk as well as the exception that caused the failure. You can implement this listener and send failed items to your error queue or log them as needed.
Related
I'm connecting MongoDB with Spring boot application, and my situation is that MongoDB goes down unexpectedly and throws connection exception, mongodb connection timeout exception and socket exception.
I'd like to capture the above exception in spring boot, and shutdown the app. I tried with #schduled from HealthIndicator which executes a simple command in DB for every 3sec and captures general exception, it works but it's not a correct approach because gives plenty of loads with multiple instances.
Unfortunately i couldn't use #controlleradvice and #exceptionhandler because don't want throwing any exception by executing query. The hitting DB with query gives loads to DB with multiple instances.
Is there any way to handle my situation?
Rather than "shutting down" your app an alternative and perhaps better solution could be to implement circuit breaker where you can provide suitable fallback for failure of remote dependencies ( in your case mongodb connection timeout). There are already good libraries which implement this out-of-the-box and very easy to configure with Spring Boot. You can check out Hystrix, Resilience4J or Sentinel.
If you still want to proceed with your earlier approach of pinging the MongoDB then you can include Actuator in your dependencies and use MongoHealthIndicator to check the status yourself. It internally runs a query
#Override
protected void doHealthCheck(Health.Builder builder) throws Exception {
Document result = this.mongoTemplate.executeCommand("{ buildInfo: 1 }");
builder.up().withDetail("version", result.getString("version"));
}
You can
An exception is thrown at Jdbctemplate.update (unique key violation).
After certain number of these exceptions the hikaripool gets timed out with connection not available (Checked and found out that this error occurs due to pool overload)
Can too many sql exceptions cause a hikariCP timeout?
Using Spring Batch's JDBCTemplate, I am trying to write data on Oracle DB. Is there any failover mechanism which can help me to process other requests if one query fails to execute ?
Catch the exception in your batch writer and log as bad records instead of throwing the exception. This will allow next chunk/batch to execute.
Our application uses WAS SIB for JMS implementation and while posting to a queue on WAS 8.5, getting following exception
javax.jms.JMSException: CWSIA0067E: An exception was received during the call to the method JmsMsgProducerImpl.: com.ibm.wsspi.sib.core.exception.SIConnectionDroppedException: CWSIJ0047E: An operation was attempted on a connection that is already closed..
at com.ibm.ws.sib.api.jms.impl.JmsMsgProducerImpl.(JmsMsgProducerImpl.java:456)
at com.ibm.ws.sib.api.jms.impl.JmsQueueSenderImpl.(JmsQueueSenderImpl.java:60)
at com.ibm.ws.sib.api.jms.impl.JmsQueueSessionImpl.instantiateProducer(JmsQueueSessionImpl.java:224)
We face the same issue.
Assumption: You are holding a connection longer than you should. In our case I suspect the persistent messaging as cause. If the underlying DB connection is dropped and you hold the JMS connection longer then this error appears.
We have what we believe is a fairly common XA use case:
read a message from an in-queue
write some data to a database
write a response message to an out-queue (which is different from the in-queue)
However we also need a way to handle internal errors and poison messages. The control flow we have in mind is something like this:
read the message from the in-queue
write to the database
if there's an exception roll back the database transaction
if there's no exception run commit phase1 on the database
if everything went fine (no rollback and commit phase1 ok) write a success message to the out-queue
if either commit phase1 on the database failed or there was an exception and the database transaction was rolled back write a failure message to the out-queue
commit the in-queue, the out-queue and the database (unless rolled by because of an exception)
Is this a good approach, should we do it differently? How can we do this with EJBs?
We're using EJB 3.1 on JBoss AS 7.2 / EAP 6.1, coding against Narayana directly is an option. The JDBC driver is ojdbc7-12.1.0.1 and the JMS RAR is MQ Series (don't know the version).
What you could do is to use the Java EE event mechanism to get a notification when your transaction fails and create a subsequent output message.
See
(EE7) http://docs.oracle.com/javaee/7/tutorial/doc/cdi-adv005.htm
(EE6) http://docs.oracle.com/javaee/6/tutorial/doc/gkhic.html
You need to use a new transaction to write to the out queue to avoid rolling back the message writing as well.
You will still have the message in the input queue which caused the exception, since the rollback will prevent the successfull consumption. You need to handle that separately, for example by the JMS provider.