Spring service layer: multiple threads accessing update method causing optimistic locking exception
===

I've run into an issue with my Spring 3 web application: 

Users can upload multiple attachments to an AttachmentParent by dragging and dropping into their browser which triggers a multipart upload. A spring controller picks up the file, creates an Attachment entity, and then sends it to the service layer where it is added to the list of attachments on the AttachmentParent. 

It works fine with one file, but if they drag multiple and they finish uploading at close to the same time then  service layer gets called multiple times, and since each file is a separate request and the service is marked @Transactional, multiple transactions are opened around the AttachmentParent at the same time. The first one closes successfully, but all the rest of them throw optimistic locking exceptions since the parent has changed since they opened and the update doesn't happen.

Here's the relevant code:

FileUploadController.java

    @RequestMapping(value = "/attach/{parentid}", method = RequestMethod.POST)
    public View handleFormUpload(@RequestParam("file") MultipartFile file, @PathVariable("parentid") long parentId, Model model) {
        AttachmentParent parent = em.find(AttachmentParent.class, parentId);
        try {
            StaticFile staticFile = fileUploader.uploadFile(file, parent.getUrl() + "/attachments/");
            Attachment a = new Attachment(staticFile.getFilename(), "", staticFile);

            attachmentService.addAttachment(parentId, a);

            //add data for the json response to the client
            model.addAttribute("name", file.getName());
            model.addAttribute("size", file.getSize());
            model.addAttribute("url", staticFile.getUrl());
            model.addAttribute("thumbnail_url", staticFile.getThumbnail_url());

        } catch (IOException e) {
            log.error("Cannot upload file");
            model.addAttribute("error", e.getMessage());
        }
        return new MappingJacksonJsonView();
    }


AttachmentService.java

    @Transactional
    public class AttachmentService extends GenericService<Attachment> {

    ...

    public void addAttachment(long parentId, Attachment attachment) {
        log.debug("Starting to add an attachment for "+parentId);
        AttachmentParent parent = em.find(AttachmentParent.class, parentId);
        attachment.setParent(parent);
        parent.addAttachment(attachment);
        log.debug("About to merge "+parent.getId());
        em.merge(parent);
    }

The output of the log messages shows the problem:

    Starting to add an attachment for 38
    Starting to add an attachment for 38
    Starting to add an attachment for 38
    About to merge 38
    About to merge 38
    About to merge 38

and the console error message while trying to close each transaction following the first:

    org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)

I'm using a spring-managed transaction manager, hibernate, and mysql5:

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager"/>


From what I understand from reading articles around the web, this is optimistic locking at work. My question is, what is the best way to solve this problem? 

Three possible solutions I've come up with:

 - Mark the service method as **synchronized** - this fixes the problem. But its more restrictive than it needs to be: the only problem is when multiple threads access the *same* attachment parent. Maybe there's a spring annotation I don't know about that allows you to use spring el to specify when a method should be synchronous? Also, I'm not sure if this will have other effects that I'm unaware of: I've never seen a service layer method marked synchronous, so am assuming it's frowned upon for some reason

 - Accept all files in the same request, and iterate over them so that each transaction gets closed before another opened. I'm guessing that this is possible, but doesn't answer the original question about transaction boundaries

 - Somehow leave a single transaction open over multiple requests. I'm not sure if this is possible but is very different from my current pattern (transaction boundary on service layer)