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