我想使用@Transactional
,希望带注释的方法获得一个单独的事务,该事务将在方法末尾提交。
但是,如果我检查数据库,则没有任何提交:
@Transactional
public boolean borrowLibraryItem(Long libraryUserId, Long uniqueLibraryItemNumber) {
boolean success = false;
LibraryUser borrower = libraryUserRepository.findByLibraryUserId(libraryUserId);
LibraryItem borrowItem = libraryItemRepository.findByUniqueLibraryItemNumber(uniqueLibraryItemNumber);
success = borrower != null && borrowItem != null;
if (success) {
BorrowedByRel borrowedByRel = new BorrowedByRel(borrower, borrowItem);
borrowedByRel.setBorrowDate(LocalDateTime.now());
borrowItem.setBorrowedByRel(borrowedByRel);
// libraryItemRepository.save(borrowItem);
}
return success;
}
使用repository.save
方法时,代码会完美地提交更改,但并非没有。
通过Spring Boot完成配置-据我了解,事情应该以这种方式开箱即用(这可能是我弄错了的部分):
@SpringBootApplication
@EnableNeo4jRepositories(basePackages = "yalms.libraryapi.repositories")
@EntityScan("yalms.libraryapi.entities")
@EnableTransactionManagement
public class YalmsLibraryApplication {
public static void main(String[] args) {
SpringApplication.run(YalmsLibraryApplication.class, args);
}
}
有关交易的事情似乎正在发生,如以下logging.level.org.springframework.transaction.interceptor=TRACE
所示:
Getting transaction for borrowLibraryItem()..
Don't need to create transaction for findByLibraryUserId, not transactional..
Request: MATCH (n:`LibraryUser`)..
Don't need to create transaction for findByUniqueLibraryItemNumber, not transactional..
Request: MATCH (n:`LibraryItem`)..
Completing transaction for borrowLibraryItem().
我希望所做的更改(添加关系)会得到落实。我是在误解这里的东西还是配置不正确的东西?任何帮助将不胜感激,在此先感谢!
更新:
我已按照评论中的建议添加了一个Neo4jTransactionManager
-Bean,很遗憾,它没有帮助解决我的问题:
@Bean
public SessionFactory sessionFactory() {
org.neo4j.ogm.config.Configuration configuration = new org.neo4j.ogm.config.Configuration.Builder()
.uri(databaseUrl)
.credentials(userName, password)
.build();
return new SessionFactory(configuration,"yalms.libraryapi");
}
@Bean
public Neo4jTransactionManager transactionManager() {
return new Neo4jTransactionManager(sessionFactory());
}
我已经启用了对来自spring.data.*
的所有内容的跟踪输出,这让我感到非常惊讶,因为看起来一切都很好:
TRACE 19634 --- [nio-8080-exec-2] .s.t.s.TransactionSynchronizationManager : Initializing transaction synchronization
TRACE 19634 --- [nio-8080-exec-2] o.s.t.i.TransactionInterceptor : Getting transaction for [yalms.libraryapi.services.BorrowService.borrowLibraryItem]
TRACE 19634 --- [nio-8080-exec-2] o.s.t.i.TransactionInterceptor : Don't need to create transaction for [org.springframework.data.neo4j.repository.support.SimpleNeo4jRepository.findByLibraryUserId]: This method isn't transactional.
DEBUG 19634 --- [nio-8080-exec-2] .s.d.n.r.q.d.DerivedGraphRepositoryQuery : Executing query for method findByLibraryUserId
TRACE 19634 --- [nio-8080-exec-2] .s.t.s.TransactionSynchronizationManager : Retrieved value [org.springframework.data.neo4j.transaction.SessionHolder@4adaed6] for key [org.neo4j.ogm.session.SessionFactory@5f4fecd0] bound to thread [http-nio-8080-exec-2]
INFO 19634 --- [nio-8080-exec-2] o.n.o.drivers.bolt.request.BoltRequest : Request: MATCH (n:`LibraryUser`) WHERE n.`libraryUserId` = { `libraryUserId_0` } WITH n RETURN n,[ [ (n)<-[r_b1:`BORROWED_BY`]-(l1:`LibraryItem`) | [ r_b1, l1 ] ] ], ID(n) with params {libraryUserId_0=0}
TRACE 19634 --- [nio-8080-exec-2] o.s.t.i.TransactionInterceptor : Don't need to create transaction for [org.springframework.data.neo4j.repository.support.SimpleNeo4jRepository.findByUniqueLibraryItemNumber]: This method isn't transactional.
DEBUG 19634 --- [nio-8080-exec-2] .s.d.n.r.q.d.DerivedGraphRepositoryQuery : Executing query for method findByUniqueLibraryItemNumber
TRACE 19634 --- [nio-8080-exec-2] .s.t.s.TransactionSynchronizationManager : Retrieved value [org.springframework.data.neo4j.transaction.SessionHolder@4adaed6] for key [org.neo4j.ogm.session.SessionFactory@5f4fecd0] bound to thread [http-nio-8080-exec-2]
INFO 19634 --- [nio-8080-exec-2] o.n.o.drivers.bolt.request.BoltRequest : Request: MATCH (n:`LibraryItem`) WHERE n.`uniqueLibraryItemNumber` = { `uniqueLibraryItemNumber_0` } WITH n RETURN n,[ [ (n)-[r_b1:`BORROWED_BY`]->(l1:`LibraryUser`) | [ r_b1, l1 ] ] ], ID(n) with params {uniqueLibraryItemNumber_0=2}
TRACE 19634 --- [nio-8080-exec-2] o.s.t.i.TransactionInterceptor : Completing transaction for [yalms.libraryapi.services.BorrowService.borrowLibraryItem]
TRACE 19634 --- [nio-8080-exec-2] o.s.d.n.t.Neo4jTransactionManager : Triggering beforeCommit synchronization
TRACE 19634 --- [nio-8080-exec-2] o.s.d.n.t.Neo4jTransactionManager : Triggering beforeCompletion synchronization
DEBUG 19634 --- [nio-8080-exec-2] o.s.d.n.t.Neo4jTransactionManager : Initiating transaction commit
DEBUG 19634 --- [nio-8080-exec-2] o.s.d.n.t.Neo4jTransactionManager : Committing Neo4j OGM transaction [org.neo4j.ogm.drivers.bolt.transaction.BoltTransaction@5a5172dc] on Session [org.neo4j.ogm.session.Neo4jSession@7dc575ae]
TRACE 19634 --- [nio-8080-exec-2] o.s.d.n.t.Neo4jTransactionManager : Triggering afterCommit synchronization
TRACE 19634 --- [nio-8080-exec-2] .s.t.s.TransactionSynchronizationManager : Clearing transaction synchronization
TRACE 19634 --- [nio-8080-exec-2] o.s.d.n.t.Neo4jTransactionManager : Triggering afterCompletion synchronization
DEBUG 19634 --- [nio-8080-exec-2] o.s.d.n.t.Neo4jTransactionManager : Not closing pre-bound Neo4j Session after transaction
TRACE 19634 --- [nio-8080-exec-2] .s.t.s.TransactionSynchronizationManager : Removed value [org.springframework.data.neo4j.transaction.SessionHolder@4adaed6] for key [org.neo4j.ogm.session.SessionFactory@5f4fecd0] from thread [http-nio-8080-exec-2]
DEBUG 19634 --- [nio-8080-exec-2] o.s.d.n.w.s.OpenSessionInViewInterceptor : Closed Neo4j OGM Session in OpenSessionInViewInterceptor
但是更新仍然不会在DB中结束-有点意义,因为没有查询可以创建新的关系,但是我不明白为什么不这样:检索到的实体似乎已附加到事务中,实体获得在交易中进行了修改,因此更改应在交易完成后提交。还是我从根本上误解了这里的内容?
答案 0 :(得分:0)
Neo4j-OGM(Spring Data Neo4j后面的对象图映射器)需要显式的save
调用。当前,这是通过显式的Spring Data Neo4j save
调用完成的。使用Spring的事务边界时没有自动提交。
基本上,您的应用程序中没有错误,显式保存调用无需注释。
关于注释的一些注释:您不需要在Spring Boot应用程序中自己定义TransactionManager
。 spring-boot-starter-neo4j
负责初始化Configuration
,SessionFactory
和适当的TransactionManager
。