Heavily nested @Transactional annotations
<p>I have inherited a Spring Java codebase where it seems pretty much every method from the business service down to the low level DAOs are tagged with @Transactional.  It has some severe performance issues that I noticed are mitigated somewhat when certain annotations are changed from @Transactional(readOnly=false) to @Transactional(readOnly=true).  It also seems to have periodic calls to EntityManager.flush() that can't be explained except that certain objects do not get written to the DB without them.</p>

<p>My hunch is that the original developers are misusing/overusing transactions, but I'm not sure of the best approach to clean this up.  I would appreciate advice from those more well-versed in Spring Transactions than me.</p>

<p>A reduced example of just one segment of the code follows.  There are others much more complex than this with 5-6 levels of nested transactions.</p>

<pre><code>// MVC Controller REST Service
@Controller
@RequestMapping("/service")
public class Group {
    @Inject private GroupService groupService;

    public @ResponseBody Object update(@RequestBody Group group) {
        return groupService.update(group);
    }
}

// Business service
@Service
public class GroupService {
    @Inject private GroupDAO groupDao;
    @Inject private AuditService auditService;

    @Transactional(readOnly=false)
    public Group update(Group group) {
        Group groupToUpdate = groupDao.get(group.getId());
        // Do magic
        groupDao.persist(groupToUpdate); // Shorthand to call EntityManager.persist()
        auditService.logUpdate(group);
        return groupToUpdate;
    }
}

// DAO
@Repository
public class GroupDAO extends AbstractDAO {
    @Transactional(readOnly=true)
    public Group get(Long id) {
        return entityManager.find(Group.class,id);
    }
}

// Auditing service
@Component
public class AuditService {
    @Inject AlertDAO alertDao;

    @Transactional(readOnly=false)
    public void logUpdate(Object o) {
        Alert alert = alertDao.getFor(o);
        // Do magic
        alertDao.update(alert);
        alertDao.flush() // Shorthand for EntityManager.flush() but WHY???
    }
}

// DAO
@Repository
public class AlertDAO extends AbstractDAO {
    @Transactional(readOnly=true)
    public Alert getFor(Object forObj) {
        // Magic here
        return entityManager.find(Alert.class,foundId);
    }

    @Transactional(readOnly=false)
    public void update(Alert a) {
        // Magic here
        entityManager.merge(a);
    }
}
</code></pre>