Почему моя транзакция неожиданно откатывается? - PullRequest
0 голосов
/ 29 мая 2020

В нашем проекте мы пытаемся получить код, который в настоящее время развернут в WebSphere, работающий над Liberty.

После получения сообщения MDB вызывает метод в службе, который вставляет данные в базу данных DB2. .

Проблема в том, что при вызове flu sh мы получаем следующие ошибки в журнале:

javax.persistence.TransactionRequiredException: no transaction is in progress
        at org.hibernate.jpa.spi.AbstractEntityManagerImpl.checkTransactionNeeded(AbstractEntityManagerImpl.java:1136) ~[hibernate-entitymanager-5.1.3.Final.jar:5.1.3.Final]
        at org.hibernate.jpa.spi.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:1297) ~[hibernate-entitymanager-5.1.3.Final.jar:5.1.3.Final]

[ERROR   ] WLTC0017E: Resources rolled back due to setRollbackOnly() being called.

Других ошибок нет, например, SQL запрос не выполняется. правильно или что-то в этом роде.

Поскольку этот код отлично работает в WebSphere, мне интересно, что-то не так в конфигурации или Liberty делает что-то другое при обработке транзакций.

Ниже соответствующие фрагменты кода и конфигурации:

@Service
public class IdentificationService implements IIdentificationService {

    @Autowired
    private IIdentificationDAO identificationDAO;

    @Transactional
    public Identification insertIdentificationData(RequestForIdentificationRequest request, String referenceNumber) {

        final Identification identification = new Identification();
        ...

        identificationDAO.create(identification);

        LOGGER.debug("Identification record saved with id: {}", identification.getId());
        return identification;
    }
}

@Repository
public class IdentificationDAO extends BaseDAO implements IIdentificationDAO {

    @Override
    public void create(final Identification identification) {
        insertRecord(identification);
    }
}

public abstract class BaseDAO
{
    @PersistenceContext(name = "UserData", unitName = "UserData")
    private EntityManager em;

    /**
     * @param record
     */
    public <T> void insertRecord(final T record)
    {
        em.persist(record);
        em.flush();
    }
}

public class Identification implements Serializable {

    @Id
    @Column(name = "ID")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
    @SequenceGenerator(sequenceName = "IDENTIFICATION_SEQ", name = "sequenceGenerator", allocationSize = 1)
    private Long id;
    ...
}

applicationContext. xml

    <jee:jndi-lookup id="userDataSource" jndi-name="jdbc/userdataDB" />

    <bean id="userDataEntityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceUnitName" value="UserData" />
        <property name="persistenceXmlLocation" value="classpath:persistence-userdata.xml" />
        <property name="dataSource" ref="userDataSource" />
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="showSql" value="true" />
                <property name="generateDdl" value="false" />
                <property name="databasePlatform" value="org.hibernate.dialect.DB2Dialect" />
            </bean>
        </property>
        <property name="loadTimeWeaver">
            <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
        </property>
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="userDataEntityManagerFactory" />
    </bean>

server. xml

    <library id="DB2JCCLib">
        <fileset dir="/etc/liberty/jdbc" includes="db2jcc4.jar, db2jcc_license_cisuz.jar, db2jcc_license_cu.jar"/>
    </library>

    <dataSource id="UserDB" jndiName="jdbc/userdataDB" type="javax.sql.XADataSource"
        isolationLevel="TRANSACTION_READ_COMMITTED">
        <jdbcDriver libraryRef="DB2JCCLib" javax.sql.XADataSource="com.ibm.db2.jcc.DB2XADataSource"/>
        <properties.db2.jcc serverName="${datasource.userdb.serverName}" portNumber="${datasource.userdb.portNumber}"
            databaseName="${datasource.userdb.databaseName}"
            user="user" password="password"/>
    </dataSource>

ОБНОВЛЕНИЕ : Проблема оказалась в нескольких bean-компонентах диспетчера транзакций (названных одинаково) в конфигурации, указывающих на разные базы данных. Назначение им уникальных имен и явная ссылка на них в аннотации транзакций помогли

...