복붙노트

[SPRING] AspectJ와의 Spring / @Transactional은 완전히 무시된다.

SPRING

AspectJ와의 Spring / @Transactional은 완전히 무시된다.

나는 Spring-Data Neo4j 2.2.0-RELEASE를 사용한다. (다음 문제는 JPA가 아닌 다른 종류의 엔티티 매핑에도 적용 가능)

내 프로젝트에서 @Transactional Spring의 주석으로 주석 처리 된 공개 메소드가 있는데, 그 내부에 엔티티를 업데이트 / 저장하고자하기 때문입니다.

public class MeetingServices {

    private UserRepository userRepository;

    private MeetingRepository meetingRepository;

    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public void setMeetingRepository(MeetingRepository meetingRepository) {
        this.meetingRepository = meetingRepository;
    }

    @Transactional("neo4jTransactionManager")
    public void save(Meeting meeting) {
        User creator = userRepository.getUserByEmail("test@test.com");
        creator.participateIn(meeting); // this line leads to a NotInTransactionException since it signals that no transaction context is associated.
        meeting.setCreator(creator);
    }

내 application-context.xml은 다음과 같습니다.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:neo4j="http://www.springframework.org/schema/data/neo4j"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/data/neo4j
       http://www.springframework.org/schema/data/neo4j/spring-neo4j.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <bean id="graphDatabaseService" class="org.neo4j.kernel.EmbeddedGraphDatabase">
        <constructor-arg value="target/neo4jgraph" />
    </bean>

    <neo4j:config graphDatabaseService="graphDatabaseService" />

    <bean id="meetingServices" class="services.MeetingServices">
        <property name="userRepository"><ref bean="userRepository"/></property>
        <property name="meetingRepository"><ref bean="meetingRepository"/></property>
    </bean>

    <bean id="userServices" class="services.UserServices">
        <property name="userRepository"><ref bean="userRepository"/></property>
    </bean>

    <bean id="neo4jTransactionManager"
        class="org.springframework.transaction.jta.JtaTransactionManager">
        <property name="transactionManager">
            <bean class="org.neo4j.kernel.impl.transaction.SpringTransactionManager">
                <constructor-arg ref="graphDatabaseService" />
            </bean>
        </property>
        <property name="userTransaction">
            <bean class="org.neo4j.kernel.impl.transaction.UserTransactionImpl">
                <constructor-arg ref="graphDatabaseService" />
            </bean>
        </property>
    </bean>

    <tx:annotation-driven mode="aspectj"
        transaction-manager="neo4jTransactionManager" />

    <!-- auto-generated repositories for Neo4j storage -->
    <neo4j:repositories base-package="repositories"/> 

    <context:spring-configured/>

    <context:annotation-config/>

</beans>

이 구성에서 볼 수 있듯이 aspectJ는 트랜잭션에 사용됩니다.

그래서, aspectJ 기능 대신 프록시 기능을 사용하기 위해 application-context.xml을 변경하여 다른 방법을 테스트하려고했습니다.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:neo4j="http://www.springframework.org/schema/data/neo4j"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/data/neo4j
       http://www.springframework.org/schema/data/neo4j/spring-neo4j.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <bean id="graphDatabaseService" class="org.neo4j.kernel.EmbeddedGraphDatabase">
        <constructor-arg value="target/neo4jgraph" />
    </bean>

    <neo4j:config graphDatabaseService="graphDatabaseService" />

    <bean id="meetingServices" class="services.MeetingServices">
        <property name="userRepository"><ref bean="userRepository"/></property>
        <property name="meetingRepository"><ref bean="meetingRepository"/></property>
    </bean>

    <bean id="userServices" class="services.UserServices">
        <property name="userRepository"><ref bean="userRepository"/></property>
    </bean>

    <tx:annotation-driven mode="proxy" />


    <neo4j:repositories base-package="repositories"/>

    <context:spring-configured/>

    <context:annotation-config/>

</beans>

이 구성은 @Transactional (neo4jTransactionManager 매개 변수가 물론 제거 되었기 때문에) 이후 잘 작동합니다. 주석은 이제 내 서비스 메소드에서 고려됩니다.

제 질문은, (내 프로젝트가 간단한 프록시 메소드로 작동하는지 여부에 관계없이) :

aspectJ 트랜잭션 기능을 실패하게 만든 첫 번째 Spring 구성에서 내가 놓치거나 잘못 설정 한 부분은 무엇인가?

저는 현재 Spring에서의 기술 능력을 향상시키고 aspectJ에 대한 "로딩 시간 짜기"에 대한 기사는 거의 읽지 않았습니다. 이게 내 문제와 관련이 있을까요?

해결법

  1. ==============================

    1.를 추가하여로드 시간 짜기를 활성화하고 spring-aspects.jar를 classpath에 추가하십시오.

    를 추가하여로드 시간 짜기를 활성화하고 spring-aspects.jar를 classpath에 추가하십시오.

    자세한 내용은 http://static.springsource.org/spring/docs/current/spring-framework-reference/html/aop.html#aop-aj-ltw-spring을 참조하십시오.

    편집하다

    일반 Java 응용 프로그램의 경우 (즉, 웹 또는 응용 프로그램 컨테이너에서 실행되지 않는 경우) javaagent 옵션을 통해 java instrumentatioin을 활성화해야합니다.

    java -javaagent:path/to/spring-instrument.jar your.Main
    

    자신 만의면을 작성하려면, aspect 선언이있는 META-INF / aop.xml 파일을 제공해야합니다. (봄용으로 만 제공되는 것은 아니며 이미 spring-aspect.jar에서 제공됩니다).

    마지막으로 maven aspectj 플러그인을 사용하여 대신 컴파일 타임 짜기를 사용할 수 있습니다. 예를 들면 다음과 같습니다.

    <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <configuration>
                    <complianceLevel>1.6</complianceLevel>
                    <aspectLibraries>
                        <aspectLibrary>
                            <groupId>org.springframework</groupId>
                            <artifactId>spring-aspects</artifactId>
                        </aspectLibrary>
                    </aspectLibraries>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
    
  2. from https://stackoverflow.com/questions/15616710/spring-transactional-with-aspectj-is-totally-ignored by cc-by-sa and MIT license