Управление Weblogic Transaction: weblogic.transaction.internal.AppSetRollbackOnlyException: setRollbackOnly вызывается для транзакции - PullRequest
0 голосов
/ 17 ноября 2018

Я чувствую, что у меня довольно специфическая проблема с источниками данных WebLogic.У меня кластер с 3 серверами.2 из которых (назовем их бэкэнд-серверами) запускают артефакты EJB каждый (разные), в то время как 3-й использует их.Все 3 из них работают на одном компьютере.

Существует 2 источника данных, каждый из которых предназначен для одного из 2 внутренних серверов, они в основном настроены одинаково, подключаясь к одному и тому же серверу базы данных (PostgreSQL) с разными пользователями и разными базами данных.

На каждом из внутренних серверов я использую Hibernate 5.3.7 с JPA 2.2.На обоих серверах артефакты развертываются успешно. С hibernate ddl, установленным на update, я вижу, что в обеих базах данных таблицы для сущностей создаются успешно, и я не вижу никаких ошибок в файлах журнала.Я использую Spring Data JPA для обоих артефактов.

Основное различие между 2 артефактами EJB заключается в том, что один из них (с которыми у меня есть проблема) использует Spring Data Redis вместе с Spring Data JPA.Это позволяет мне не доверять Spring для создания репозиториев для меня, даже для JPA (afaik spring-data-redis не предоставляет реализацию для репозиториев).Я создал продюсера, который делает это для меня:

public class RepositoryConfiguration {

    @Inject
    private EntityManager entityManager;

    @Produces
    @RequestScoped
    public UserRepository userRepository() {
        return createRepository(UserRepository.class);
    }

    private <T extends Repository> T createRepository(Class<T> repositoryClass) {
        RepositoryFactorySupport factory = new JpaRepositoryFactory(entityManager);
        return factory.getRepository(repositoryClass);
    }
}

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

Фактическая проблема, с которой я сталкиваюсь, - это когда я пытаюсь прочитать данные из UserRepository, я получаю исключение:

java.sql.SQLException: Transaction BEA1-0002E54B992150673EDF not active anymore. tx status = Marked rollback. [Reason=weblogic.transaction.internal.AppSetRollbackOnlyException: setRollbackOnly called on transaction]
        at weblogic.jdbc.jts.Driver.getTransaction(Driver.java:560) ~[com.bea.core.datasource6.jar:12.2.1.3]
        at weblogic.jdbc.jts.Driver.connect(Driver.java:114) ~[com.bea.core.datasource6.jar:12.2.1.3]
        at weblogic.jdbc.common.internal.RmiDataSource.getConnectionInternal(RmiDataSource.java:638) ~[com.bea.core.datasource6.jar:12.2.1.3]
        at weblogic.jdbc.common.internal.RmiDataSource.getConnection(RmiDataSource.java:594) ~[com.bea.core.datasource6.jar:12.2.1.3]
        at weblogic.jdbc.common.internal.RmiDataSource.getConnection(RmiDataSource.java:587) ~[com.bea.core.datasource6.jar:12.2.1.3]
        at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122) ~[org.hibernate-hibernate-core-5.3.7.Final.jar:5.3.7.Final]
        at org.hibernate.internal.NonContextualJdbcConnectionAccess.obtainConnection(NonContextualJdbcConnectionAccess.java:35) ~[org.hibernate-hibernate-core-5.3.7.Final.jar:5.3.7.Final]
        at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:106) ~[org.hibernate-hibernate-core-5.3.7.Final.jar:5.3.7.Final]

У меня есть компонент, создающий экземпляр EntityManager:

@PersistenceContext(name = "UsersDS")
private EntityManager em;

@Produces
@RequestScoped
public EntityManager getEntityManager() {
    log.trace("EntityManager requested");
    return em;
}

Рассматриваемый код, генерирующий исключение:

@Slf4j
@Stateless(name = "AuthenticationService")
public class AuthenticationServiceImpl implements AuthenticationService {

    @Inject
    private AuthenticationRepository authenticationRepository;

    @Inject
    private UserRepository userRepository;

    @Inject
    public AuthenticationServiceImpl() {
    }

    // ....

    @Override
    @Transactional
    public TokenState getTokenState(AuthenticationToken token) {
        log.trace("Searching {} in the userRepository", token);
        Optional<UserEntity> user = userRepository.findByUsername(token.getPrincipal())
                .filter(userEntity -> userEntity.getPassword().equals(token.getCredentials()));
        if (!user.isPresent()) {
            authenticationRepository.delete(token);
            return TokenState.INVALID;
        }

        switch (user.get().getState()) {
            case ACTIVE:
                return authenticationRepository.existsById(token.getSessionId()) ?
                        TokenState.AUTHENTICATED : TokenState.UNAUTHENTICATED;
            case LOCKED:
                return TokenState.LOCKED;
            case INACTIVE:
                return TokenState.DISABLED;

            default:
                return TokenState.INVALID;
        }
    }
}

У меня есть интеграционные тесты, которые запускают базу данных in-mem H2 и встроенную базу данных Redis с управляемым вручную EntityManager, который работает без каких-либопроблемы.

Кто-нибудь может дать мне совет, как мне решить эту проблему?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...