@Transactional:在事务结束时不提交;使用Spring Boot和neo4j

时间:2018-10-24 19:30:27

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

我想使用@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中结束-有点意义,因为没有查询可以创建新的关系,但是我不明白为什么不这样:检索到的实体似乎已附加到事务中,实体获得在交易中进行了修改,因此更改应在交易完成后提交。还是我从根本上误解了这里的内容?

1 个答案:

答案 0 :(得分:0)

Neo4j-OGM(Spring Data Neo4j后面的对象图映射器)需要显式的save调用。当前,这是通过显式的Spring Data Neo4j save调用完成的。使用Spring的事务边界时没有自动提交。

基本上,您的应用程序中没有错误,显式保存调用无需注释。

关于注释的一些注释:您不需要在Spring Boot应用程序中自己定义TransactionManagerspring-boot-starter-neo4j负责初始化ConfigurationSessionFactory和适当的TransactionManager