Apache Ignite не удалось десериализовать объект с заданным загрузчиком классов при запуске (клиент-сервер)

#java #transactions #ignite

#java #транзакции #ignite

Вопрос:

Я пытаюсь использовать пользовательский диспетчер транзакций с ignite, однако это приводит к невозможности десериализации объекта с заданным загрузчиком классов при запуске. Фабрика диспетчера транзакций реализована как

 public class TransactionManagerFactory implements Factory<TransactionManager> {
private static final long serialVersionUID = 1L;

private TransactionManager txMgr;

public TransactionManagerFactory(TransactionManager txMgr) {
    this.txMgr=txMgr;
}

@Override
public TransactionManager create() {
    return this.txMgr;
}
}
 

Завод привязан к конфигурации клиента следующим образом:

 TransactionConfiguration txConfiguration=new TransactionConfiguration();
txConfiguration.setDeadlockTimeout(acquireTimeout);
txConfiguration.setDefaultTxIsolation(TransactionIsolation.READ_COMMITTED);
txConfiguration.setDefaultTxConcurrency(TransactionConcurrency.PESSIMISTIC);
txConfiguration.setTxManagerFactory(new TransactionManagerFactory(txMgr));           
this.clientConfig.setTransactionConfiguration(txConfiguration);
 

Ошибка говорит, что сам диспетчер транзакций, переданный на завод, не сериализуем:
Вызвано: java.io.NotSerializableException: org.infinispan.transaction.tm.EmbeddedBaseTransactionManager

Однако сам диспетчер транзакций не должен быть сериализуемым. Как мы можем передать существующий диспетчер транзакций клиенту ignite?

Юлиан Ойфа

Ответ №1:

Ваша фабрика диспетчера транзакций сохраняет экземпляр диспетчера транзакций вместо того, чтобы создавать его в create() методе на удаленном узле. Вот как это должно работать.

Все нестационарные поля сериализуемого объекта также должны быть сериализуемыми.

Комментарии:

1. Привет, и спасибо за ваш ответ. Означает ли это, что транзакция будет выполнена на удаленном узле? Цель состоит в том, чтобы повторно использовать тот же диспетчер транзакций, который используется приложением (для тестирования мы используем infinispan embedded, для самого приложения мы используем wildfly transaciton manager) для операций с кэшем и для других операций, выполняемых приложением, требующим транзакции. В случае, если транзакция будет выполняться на удаленном узле, у нас фактически будет 2 разные транзакции -> одна локальная и одна удаленная, и в результате, если локальная транзакция будет откатываться, удаленная не будет…

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

3. Спасибо, я попытался установить диспетчер как переходный, однако это не помогло. После локального вызова TransactionManager.begin() ignite не увидел эту локальную транзакцию: TransactionImpl{xid=Xid{formatId=1, globalTransactionId=BC046B9DF444943A22C2BC05A84B4D110000000000000002,branchQualifier=BC046B9DF444943A22C2BC05A84B4D110000000000000002} , status=АКТИВНЫЙ},Ignite:null, где первая часть регистрирует TransactionManager.transaction() , а второй экземпляр.transactions().tx()

4. Я думаю, это не связано с самим менеджером транзакций. Проблема в том, что create никогда не вызывается для диспетчера транзакций