Есть ли какое-либо решение для обработки транзакций путем определения в абстрактном классе конкретного метода? - PullRequest
0 голосов
/ 10 января 2019

Я определяю функцию Transaction в моем приложении, но она не работает для класса Abstract метода Concrete, так как мой контроллер вызывает первый метод класса Abstract, тогда он войдет в метод класса Concrete. Может кто-нибудь помочь мне исправить? Я пытался использовать метод класса Concrete, он работает, но мне нужно перенести его на абстрактный слой, так как я вызываю функцию DAO операции CRUD только в абстрактном слое.

Я попытался вставить данные для нескольких таблиц и, наконец, выдал исключение, чтобы убедиться, что транзакция должна откатываться. Но данные захватывают, хотя и происходит исключение.

 --Controller code Start
@RequestMapping(value = "/new", method = RequestMethod.GET)
public String add() throws Exception {

    addDTO();
    return "demo";

}

protected void addDTO() {

    try {
        service.addDTO();
    } catch (Exception e) {
        log.error("addDTO", e);
    }
}

 --- Controller code End


 --- Abstract Service with concrete method
@Override
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = { Exception.class })
public void addDTO() throws Exception {
    try {

        E entity = this.entityFromDTO();
        this.dao.add(entity);

        // Added For Transaction Test START
        TMstPackage packType = getPackageEntity();
        mstPackageDao.add(packType);

        throw new Exception("Transaction RollBack test");

        // Added For Transaction Test END

    } catch (Exception ex) {
        Log.error("addData");
        throw ex;
    }

}

 --- Concrete Service
@Override
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = { Exception.class })
protected TMstContainer entityFromDTO() throws Exception {

    TMstContainer container = null;
    try {
        Date date = Calendar.getInstance().getTime();
        container = new TMstContainer();
        container.setCntCode("TEST1");
        container.setCntDescription("Test Desc");

        container.setCntDtCreate(date);
        container.setCntDtLupd(date);
        container.setCntStatus('A');
        container.setCntUidCreate("SYS");
        container.setCntUidLupd("SYS");

    } catch (Exception e) {
        log.error(e);
    }
     return container;
}

Тот же код, который я пробовал, определив в конкретном классе функцию с помощью @Transactional, все работает отлично. Но если я приведу это к абстрактной функции с той же аннотацией, данные будут записаны в базу данных. Может кто-нибудь, пожалуйста, помогите.

Изображение для абстрактного класса с конкретным методом и определенной аннотацией @Transactional:

enter image description here

1 Ответ

0 голосов
/ 10 января 2019

Это ожидаемое поведение. Метод @Transactional должен вызываться напрямую извне, в этом случае экземпляр объекта должен быть получен с помощью пружинного впрыска. Весна здесь не творит волшебство. он создает прокси-сервер AOP для указанного вами класса, и если кто-то вызывает метод, использующий этот прокси-сервер, если метод аннотирован как @Transactional, этот обработчик вызова метода прокси-сервера выполнит его через шаблон транзакции. если вы вызываете транснациональный метод непосредственно из не транснационального метода в этом классе, Spring ничего не знает.

...