Search code examples
javatransactionsapache-camelrollbackfile-writing

How to rollback file writes when using Apache Camel transaction?


I am using a multicast route in Camel with two pipelines. One pipeline adds the data into database and other does some write operations on a file. My requirement to rollback the complete process in case of failure or any error. I have successfully rolled back the db insertions, but not able to find out any way to rollback write operations done on the file. Can anybody help me out with the rollback process. Here is my route context:

    <routeContext id="s1Route" xmlns="http://camel.apache.org/schema/spring">
    <route id="sRoute">
        <from uri="activemq:queue:{{s.queue}}" />
        <log message="Message received from myprocess queue is ${body}"></log>
        <unmarshal ref="gsonUnmarshelling"></unmarshal>
        <bean beanType="com.***.upload.***.GetMyBean"
            method="process(com.**.upload.beans.MyEvenets,${exchange})" />
        <log message="Multicasting  data ${body} to file system and database" />
        <multicast parallelProcessing="true">
            <pipeline>
                <choice>
                    <when>
                        <simple>${properties:s.write.file} == true</simple>
                        <setHeader headerName="path">
                            <simple>${properties:s.write.folder}</simple>
                        </setHeader>
                        <log message="Going to write to file : ${body}"></log>
                        <bean beanType="com.***.upload.processors.ToFile"
                            method="process(${exchange},com.***.upload.beans.MyFile)" />
                        <to uri="file://?fileExist=Append"></to>
                    </when>
                </choice>
            </pipeline>
            <pipeline>
                <log message="Going to insert in database"></log>
                <transform>
                    <method ref="insertBean" method="MyBatchInsertion"></method>
                </transform>
                <choice>
                    <when>
                        <simple>${in.header.myCount} == ${properties:batch.size}</simple>
                        <to uri="sql:{{sql.my.insertBatch}}?batch=true"></to>
                        <log message="Inserted rows ${body}"></log>
                    </when>
                </choice>
            </pipeline>
        </multicast>
    </route>
</routeContext>

Solution

  • Apache Commons Transaction can deal with transactional read and write operations on any file system.

    You can setup your processor com.***.upload.processors.ToFile to handle read and write operations transactionally in process() method.

    This SO Apache Transaction:write file transactionally - how to use resourceId can help integrating common transaction in your code.