@Transactional没有效果

时间:2013-09-05 15:56:32

标签: java spring neo4j spring-transactions spring-data-neo4j

我目前遇到的问题是@Transactional注释似乎没有为Neo4j启动事务,但是(它不适用于我的任何 @Transactional 注释方法,而不仅仅是以下例子。)

示例:

我有这个方法(UserService.createUser),它首先在Neo4j图中创建一个用户节点,然后在MongoDB中创建用户(带有附加信息)。 (MongoDB不支持事务,因此首先创建用户节点,然后将实体插入MongoDB并随后提交Neo4j事务。)

该方法使用@Transactional注释,但在Neo4j中创建用户时会抛出org.neo4j.graphdb.NotInTransactionException

以下是我的配置和编码:

基于代码的SDN-Neo4j配置:

@Configuration
@EnableTransactionManagement                        // mode = proxy
@EnableNeo4jRepositories(basePackages = "graph.repository")
public class Neo4jConfig extends Neo4jConfiguration {
    private static final String DB_PATH = "path_to.db";
    private static final String CONFIG_PATH = "path_to.properties";

    @Bean(destroyMethod = "shutdown")
    public GraphDatabaseService graphDatabaseService() {
        return new GraphDatabaseFactory().newEmbeddedDatabaseBuilder(DB_PATH)
            .loadPropertiesFromFile(CONFIG_PATH).newGraphDatabase();
    }
}

在Neo4j和MongoDB中创建用户的服务:

@Service
public class UserService {
    @Inject
    private UserMdbRepository mdbUserRepository;    // MongoRepository
    @Inject
    private Neo4jTemplate neo4jTemplate;

    @Transactional
    public User createUser(User user) {
        // Create the graph-node first, because if this fails the user
        // shall not be created in the MongoDB
        this.neo4jTemplate.save(user);              // NotInTransactionException is thrown here
        // Then create the MongoDB-user. This can't be rolled back, but
        // if this fails, the Neo4j-modification shall be rolled back too
        return this.mdbUserRepository.save(user);
    }

    ...
}

侧面说明:

  • 我使用的是春季版3.2.3.RELEASE和spring-data-neo4j版本2.3.0.M1
  • UserService Neo4jConfig 位于单独的Maven工件中
  • 到目前为止,启动服务器和SDN读取操作工作,我只是在编写操作时遇到麻烦
  • 我目前正将项目从tinkerpop-framework迁移到SDN-Neo4j。这个用户创建过程之前有过(使用tinkerpop),我只需要再次使用SDN-Neo4j。
  • 我在Jetty中运行应用程序

有没有人知道为什么这还不行?(

我希望,这些信息已经足够了。如果遗漏了任何内容,请告诉我,我会添加它。


修改

我忘了提到手动交易处理工作,但我当然希望以“它本来就是”的方式实现它。

    public User createUser(User user) throws ServiceException {
        Transaction tx = this.graphDatabaseService.beginTx();
        try {
            this.neo4jTemplate.save(user);
            User persistantUser = this.mdbUserRepository.save(user);
            tx.success();
            return persistantUser;
        } catch (Exception e) {
            tx.failure();
            throw new ServiceException(e);
        } finally {
            tx.finish();
        }
    }

1 个答案:

答案 0 :(得分:0)

感谢m-deinum我终于找到了这个问题。问题是我在不同的spring-configuration文件中扫描了那些组件/服务,而不是我配置SDN-Neo4j。我将组件扫描移动到那些可能需要交易的软件包到我的Neo4jConfig,现在它可以正常工作

@Configuration
@EnableTransactionManagement                        // mode = proxy
@EnableNeo4jRepositories(basePackages = "graph.repository")
@ComponentScan({
    "graph.component",
    "graph.service",
    "core.service"
})
public class Neo4jConfig extends Neo4jConfiguration {
    private static final String DB_PATH = "path_to.db";
    private static final String CONFIG_PATH = "path_to.properties";

    @Bean(destroyMethod = "shutdown")
    public GraphDatabaseService graphDatabaseService() {
        return new GraphDatabaseFactory().newEmbeddedDatabaseBuilder(DB_PATH)
            .loadPropertiesFromFile(CONFIG_PATH).newGraphDatabase();
    }
}

但我仍然需要将那些需要交易的组件/服务与那些不需要交易的组件/服务分开。但是,这暂时有效。

我认为问题是其他spring-configuration-file(包括组件扫描)在Neo4jConfig之前加载,因为neo4j:repositories必须放在context:component-scan之前。 (参见例20.26中的注意。编写存储库http://static.springsource.org/spring-data/data-neo4j/docs/current/reference/html/programming-model.html#d0e2948