O
O
Oleg Yakovenko2015-07-24 15:17:23
Java
Oleg Yakovenko, 2015-07-24 15:17:23

Spring transactions and spring data rest. Why are transactions not working?

Good day.
I am writing with this problem. There is a web project with spring. Frontend in angular, rests are displayed using spring-data-rest. Everything is convenient, good, great, but!
It's time to deal with distributed transactions. I will describe the case. There are objects with references to themselves. Example

public class SystemObject{
    SystemObject parent;
    List<AttributeInfo> attributes;
}

SystemObject depending on some other data can either live or not live without parent'a.
attributes are always deleted cascaded together with SystemObject (well, it is clear that within one transaction).
Question with deleting subordinate objects.
In Jpa repositories I did the following.
@Override
    @Transactional(value = "transactionManager", readOnly = false, propagation = Propagation.REQUIRES_NEW, rollbackFor= Exception.class)
    void delete(String s);

    @Override
    @Transactional(value = "transactionManager", readOnly = false, propagation = Propagation.REQUIRES_NEW, rollbackFor= Exception.class)
    void delete(SystemObject paramT);

    @Override
    @RestResource(exported = false)
    @Transactional(value = "transactionManager", readOnly = false, propagation = Propagation.MANDATORY, rollbackFor = Exception.class)
    void delete(Iterable<? extends SystemObject> iterable);

    @Modifying
    @Transactional(value = "transactionManager", readOnly = false, propagation = Propagation.MANDATORY, rollbackFor = Exception.class)
    @Query(value = "UPDATE SystemObject i SET i.parent = null WHERE i.parent = :parent AND i.objectType.isTableType = false")
    @RestResource(exported = false)
    int releaseChildren(@Param("parent") SystemObject parent);

Created an EventHanlder for SystemObject with the following code.
@Override
    @Transactional(value = "transactionManager", readOnly = false, propagation = Propagation.MANDATORY, rollbackFor = Exception.class)
    protected void onBeforeDelete(SystemObject entity) {
        //Зануляет объекты которые могут жить без родителя
        objectRepository.releaseChildren(entity);
        //Смотрю есть ли смертники и удаляю их
        List<SystemObject> relatedObjects = objectRepository.getRelatedObjects(entity.getId());
        if(relatedObjects != null){
            LOG.info("Deleting related objects for entity {}",entity.getId());
            objectRepository.delete(relatedObjects);
            LOG.info("Deleting successful");
        } else {
            LOG.info("No related objects to delete. Entity {}",entity.getId() );
        }
    }

When propogation Mandatory I immediately catch an exception that there is no transaction. If you put Supports, everything will be deleted, but not in one transaction. (checked by throwing an exception after the Deletion message in the handler, only attributes were restored, SystemObject's subordinates crashed forever).
The question is the following, the hat with transactions occurs for the same reason that it is impossible to make poincuts in AspectJ in proxy classes (because if the pointcut crashes into the package name, then it will not crash into com.sun.$Proxy at runtime) ?
And is it possible somehow to implement this without resorting to creating your own rest, in which all the deletion logic will be sequentially called within a single transaction (not sure).

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question