SDN 迁移到 4.2:@Transactional 如何工作?

SDN Migration to 4.2: How does @Transactional works?

我正在尝试将 SDN (4.2.0.M1) 和 neo4j-ogm (2.0.5) 版本升级到最新的快照 4.2.0.BUILD-SNAPSHOT2.1.0-SNAPSHOT

根据迁移指南和其他 SO 问题的一些建议,我将所有与 neo4j session 交互的方法包装为 @Transactional。它在大多数情况下工作正常,但仍有一些我无法理解的例外情况 (Transaction is not current for this thread)。

举个例子:

@Service
public class ContactServiceImpl implements ContactService {

    @Inject
    private Session session;

    //...

    @Override
    @Transactional
    public void addContact(String userId, String contactId) {
        Contact contact = new Contact();
        // Fill contact data

        session.save(contact);
    }

    @Override
    public void addContacts(String userId, Set<User> newContacts) {
        for (User contact : CollectionUtils.emptyIfNull(newContacts)) {
            addContact(userId, contact.getId());
        }
    }   
}

这里我只用@Transaction注释了addContact方法,因为它是唯一直接与SDN交互的方法,至少我是这么想的:)

但是,如果我调用 addContacts 方法,它只是迭代一个列表并调用带注释的 addContact 方法,它会失败并出现前面提到的异常。如果我也注释这个方法,它只是工作得很好,但我不明白为什么。也许我缺少一些关于 spring @Transactional 注释行为的基础知识,很抱歉,如果这是一个无脑的问题。

任何人都可以解释为什么我需要注释这两种方法吗? 提前致谢

@Transactional 比大多数人想象的要复杂一些。看起来应该起作用的东西实际上不起作用,有时反之亦然。

在您的案例中,您遇到了一个不友好的 Spring 问题:不理解 @Transactional 在从同一 class 调用事务方法时 AOP 代理是如何工作的.

This snippet from the official documenation 是一个很好的起点,可以粗略了解 Spring 的事务代理的基础知识。

我快速搜索 Whosebug this answer,它很好地解释了您所看到的现象。

注意: 从 4.2 版开始,SDN 现在完全实现了 Spring 交易平台。