Спящий |Почему сделка "наполовину совершена" - PullRequest
0 голосов
/ 25 октября 2018

Я работаю с Hibernate в проекте Spring Boot.

У меня есть следующий фрагмент кода:

public class SomeService {

    private Dependency dependency;

    @Transactional(readOnly=false)
    public void doSomething() {
        //some BL code...

        dependency.doSomeDbManipualation();

        someOperation();
    }

    public void someOperation() {
        //some code that eventually fails
    }
}

public class Dependency {

    public void doSomeDbManipulation() {
        Entity entity = ...; //get the entity from current session by its key
        if (entity != null) {
            session.delete(entity);
        }

        OtherEntity oEntity = new OtherEntity();
        //set its fields
        Long oEntityId = session.save(oEntity);

        entity = new Entity();
        entity.setForeignKey(oEntityId);
        //set other fields
        session.persist(entity);
    }
}

Теперь у меня в базе данных есть объект с соответствующимключ.Поэтому я ожидаю, что при вызове службы код, который ищет сущность, действительно найдет ее.Но так как someOperation() завершается ошибкой, я ожидаю увидеть никаких изменений в БД.

На самом деле, после вызова someService.doSomething() (и сбоя) я смотрю в БД и вижу, что существующая сущность была удалена!Но новая сущность не была создана (что нормально).

Почему эта транзакция "наполовину зафиксирована"?

РЕДАКТИРОВАТЬ: Видимо delete () и save ()совершаются немедленно.Когда я отлаживаю, я вижу, что сущность сразу удаляется после завершения этой строки в коде.Также OtherEntity добавляется немедленно в БД.persist () не фиксируется немедленно.

Я использую AspectJ для управления транзакциями.Вот соответствующая часть из моего pom.xml:

<project>
    ...
    <dependencies>
        ...
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
        </dependency>
        ...
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.7</version>
                <dependencies>
                    <dependency>
                        <groupId>org.aspectj</groupId>
                        <artifactId>aspectjtools</artifactId>
                        <version>1.8.3</version>
                    </dependency>
                </dependencies>
                <configuration>
                    <showWeaveInfo>true</showWeaveInfo>
                    <outxml>true</outxml>
                    <forceAjcCompile>true</forceAjcCompile>
                    <source>1.8</source>
                    <target>1.8</target>
                    <Xlint>ignore</Xlint>
                    <complianceLevel>1.8</complianceLevel>
                    <encoding>UTF-8</encoding>
                    <verbose>true</verbose>
                    <preserveAllLocals>true</preserveAllLocals>
                    <aspectLibraries>
                        <aspectLibrary>
                            <groupId>org.springframework</groupId>
                            <artifactId>spring-aspects</artifactId>
                        </aspectLibrary>
                    </aspectLibraries>
                </configuration>
                <executions>
                    <execution>
                        <id>AspectJ-Compile</id>
                        <phase>process-classes</phase>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
        ...
    </build>
</project>

Ответы [ 2 ]

0 голосов
/ 29 октября 2018

Я нашел решение проблемы.У меня было несколько аннотаций @ComponentScan в нескольких классах.Когда я удалил их все и оставил только один, все работало как ожидалось.

Я не понимаю причину этого странного поведения, поэтому я разместил отдельный вопрос по этому поводу, здесь

0 голосов
/ 28 октября 2018

Я не знаю, почему аспект j явно добавляется как зависимость в pom file.if, если вы используете весеннюю загрузку, вы получаете аспекты из коробки. Я видел непредсказуемое поведение, когда в пути к классам присутствуют дубликаты jar.

Также я не смог понять, почему метод манипуляции с БД вызывается из метода, который сам помечен для транзакции только для чтения.

Я чувствую, что дизайн здесь не правильный.

...