有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java@Transactional没有效果

我目前的问题是@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);
    }

    ...
}

旁注:

  • 我使用的是spring版本3.2.3.RELEASE和spring-data-neo4j版本2.3.0.M1
  • UserServiceNeo4jConfig在单独的Maven工件中
  • 启动服务器和SDN读取操作到目前为止,我只是在写操作方面遇到了问题
  • 我目前正在将我们的项目从tinkerpop框架迁移到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) 个答案

  1. # 1 楼答案

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