I've recently begun using Spring's Data Source Transaction Manager. I have a problem now. My transaction includes updates to a DB table and a write operation to a file.
It works fine but I have some doubts about file I/O. As you see below, I have configured openFile and closeFile methods of my bean as the init-method and the destroy-method respectively, which in turn provides those methods to be called just like a constuructor and a destructor. If the file is not closed properly, some of the records may not have successfully been written to the output.txt file which means that I have not been able to handle transaction management properly as well.
However, I'd like to rollback those DB updates which have not been appended to the flat file. With my solution, it looks impossible to add the fileClose method to the transaction. Does anyone know how to implement this desired action properly?
Any suggestions would be greatly appreciated
<!--XML CONFIGURATION -->
<bean id="myFileWriter" class="com.job.step.ItemFileWriter" init-method="openFile" destroy-method="closeFile">
<property name="jdbcTemplate" ref="jdbcTemplateProduct"/>
</bean>
public class ItemFileWriter implements ItemWriter<Item> {
private static final Logger log = Logger.getLogger(ItemFileWriter.class);
private BufferedWriter bw = null;
public void openFile() throws IOException {
try {
bw = new BufferedWriter(new FileWriter("C:\\output.txt"));
} catch (IOException e) {
//log.error(e);
throw e;
}
}
public void closeFile() throws IOException {
if (bw != null) {
try {
bw.close();
} catch (IOException e) {
log.error(e);
throw e;
}
}
}
@Transactional(rollbackFor = IOException.class)
public void write(List<? extends Item> itemList) throws IOException
{
for (Iterator<? extends Item> iterator = itemList.iterator(); iterator.hasNext();) {
Item item = (Item) iterator.next();
String updateRtlnOutbound = "UPDATE SAMPLESCHEMA.SAMPLETABLE SET STATUS='TRANSFERRED' WHERE ID = ?";
jdbcTemplate.update(updateRtlnOutbound, new Object[]{item.getID()});
String item = String.format("%09d\n", item.customerNumber);
bw.write(item);
}
}
}