Доброго времени суток.
Пишу с такой вот проблемой. Есть веб проект со спрингом. Фронтэнд на ангуляре, ресты выводятся при помощи spring-data-rest. Всё удобно, хорошо, здорово, но!
Пришло время заниматься расрпделёнными транзакциями. Опишу случай. Есть объекты, с ссылками на себя. Пример
public class SystemObject{
SystemObject parent;
List<AttributeInfo> attributes;
}
SystemObject в зависимости от некоторых других данных может либо жить, либо не жить без parent'a.
attributes удаляются каскадно вместе с SystemObject всегда (ну и понятно что в рамках одной транзакции).
Вопрос с удалением подчинённых объектов.
В Jpa репозитории сделал следующее.
@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);
Создал EventHanlder для SystemObject со следующим кодом.
@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() );
}
}
При propogation Mandatory сразу же ловлю исключение, что транзакции нет. Если поставить Supports, всё будет удалено, но не в одной транзакции. (проверил выкинув исключение после Сообщения об удалении в handler, восстановились только attributes, подчинённые SystemObject's грохнулись навсегда).
Вопрос следующий, шляпа с транзакциями происходит по той же причине, по которой нельзя в proxy классы сделать poincut'ы в AspectJ (поскольку если поинткат врезается в package name то в рантайме в com.sun.$Proxy он не врежется) ?
И можно ли как-то это всё же реализовать, не прибегая к созданию своего реста, в котором будет последовательно вызвана вся логика удаления в рамках одной транзакции (не уверен).