Альтернатива Neo4jTransactionManager для соблюдения изоляции REQUIRES_NEW - PullRequest
0 голосов
/ 06 июля 2019

Я использую пружинную загрузку 2 и зависимость neo4j от data (которая, я думаю, приносит sdn 5.x) в дополнение к neo4j-ogm 3.1.1 для управления моим постоянством.Я отметил, что Neo4jTransactionManager по умолчанию не поддерживает вложенные транзакции или требует нового распространения.

Я хотел бы, чтобы мой метод обслуживания выполнял, по существу, несколько шагов в отдельных транзакциях.

Для достижения того, что я хочу, я прибегнул к поддержке асинхронной / многопоточности Spring, чтобы эффективно форсировать новый сеанс и транзакцию по шагам в моем методе обслуживания, как показано ниже.Что я хотел бы знать, есть ли лучший способ решить эту проблему?

Мне кажется, что я могу легко создавать отдельные транзакции / единицы работы, но готовое решение data neo4j для пружин ограничивает это.

Мой метод обслуживания, первый шагЯ хочу изолировать уже в отдельном сервисе, отмеченном здесь вызовом connectionService.deleteDiagramConnections (figure.getId ());

@Retryable(value = TransientException.class,exceptionExpression="#{message.contains('RWLock')}", maxAttempts = 5)
    public Diagram update(final Diagram diagram) throws GUMLException {

        AtomicReference<Diagram> result = new AtomicReference<Diagram>();
        AtomicReference<Object> isComplete = new AtomicReference<Object>();
        isComplete.set(false);

        ListenableFuture future = connectionService.deleteDiagramConnections(diagram.getId());
        future.addCallback(new ListenableFutureCallback() {
            @Override
            public void onFailure(Throwable throwable) {
                logger.error(throwable);
            }

            @Override
            public void onSuccess(Object o) {

                for (Connection connection : diagram.getConnections()) {
                    connection.setId(null);
                    if (connection.getId() != null && connection.getMoveablePoints() != null) {
                        for (MoveablePoint mp : connection.getMoveablePoints()) {
                            mp.setId(null);
                        }
                    }
                }
                isComplete.set(true);



            }
        });


        while ((boolean)isComplete.get() == false) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new GUMLException(Severity.ERROR, e.getMessage());
            }
            if ((boolean)isComplete.get() == true)
                result.set(umlDiagramRepository.save(diagram));

        }

        return result.get();

    }

Служба соединения:

@Async
    @Override
    public ListenableFuture<String> deleteDiagramConnections(long diagramId) throws GUMLException {

        connectionRepository.deleteDiagramConnections(diagramId);
        return new AsyncResult<String>("delete complete");
    }

ВотКонфигурация моего тестового приложения

@org.springframework.context.annotation.Configuration
@ComponentScan(basePackages = "au.com.guml", lazyInit = true)
@EnableTransactionManagement
@EnableAsync
public class TestConfig {

    @Bean
    public org.neo4j.ogm.config.Configuration configuration() {
        org.neo4j.ogm.config.Configuration configuration = new org.neo4j.ogm.config.Configuration.Builder()
                .uri("bolt://localhost")
                .credentials("neo4j", "password")
                .build();
        return configuration;
    }

//    @Bean
//    public org.neo4j.ogm.config.Configuration configuration() {
//        org.neo4j.ogm.config.Configuration configuration = new org.neo4j.ogm.config.Configuration.Builder()
//                .uri("http://neo4j:password@localhost:7474")
//                .build();
//        return configuration;
//    }

//    @Bean
//    public Configuration getConfiguration() {
//
//        Configuration config = new Configuration();
//        config
//                .driverConfiguration()
//                .setDriverClassName("org.neo4j.ogm.drivers.http.driver.HttpDriver")
//                .setURI("http://neo4j:password@localhost:7474")
//                .setCredentials("neo4j","password");
//
//        return config;
//    }

    @Bean
    public SessionFactory sessionFactory() {
        // with domain entity base package(s)
        return new SessionFactory(configuration() ,"au.com.guml.domain");
    }


    @Bean
    public Neo4jTransactionManager transactionManager() {
        return new Neo4jTransactionManager(sessionFactory());
    }

//    @Bean
//    public TaskExecutor syncTaskExecutor () {
//        SyncTaskExecutor syncTaskExecutor = new SyncTaskExecutor();
//        return syncTaskExecutor;
//    }

    @Bean
    public TaskExecutor threadPoolTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(4);
        executor.setMaxPoolSize(4);
        executor.setThreadNamePrefix("default_task_executor_thread");
        executor.initialize();
        return executor;
    }

}

1 Ответ

0 голосов
/ 07 июля 2019

Получается, что все, что мне нужно было сделать, это внедрить сеанс neo4j ogm в мою службу и вызвать session.getTransaction().commit();

Затем я установил нулевые идентификаторы подключения в моем внешнем вызове службы, и все они были добавленыкак будто они новые.

...