0

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

例子:

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

在 Neo4j 中创建用户时,该方法被注释了@Transactional但被抛出。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);
    }

    ...
}

旁注:

  • 我正在使用 spring 版本3.2.3.RELEASE和 spring-data-neo4j 版本2.3.0.M1
  • UserServiceNeo4jConfig位于不同的 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();
        }
    }
4

1 回答 1

0

感谢 m-deinum,我终于找到了问题所在。问题是我在不同的 spring-configuration-file 中扫描了这些组件/服务,而不是在我配置 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(包括组件扫描)是 before 加载的Neo4jConfig,因为neo4j:repositories必须放在 before context:component-scan。(参见示例 20.26 中的注释。组合存储库http://static.springsource.org/spring-data/data-neo4j/docs/current/reference/html/programming-model.html#d0e2948

于 2013-09-06T14:22:16.163 回答