Наблюдение TransactionRequiredException: выполнение запроса на обновление / удаление при использовании программных транзакций Spring с HIbernate 5 - PullRequest
0 голосов
/ 01 декабря 2018

У меня возникают проблемы с весенними программными транзакциями при использовании шаблона транзакции.Это всегда выдает следующее исключение. (Я использовал Spring 5.1.3 и Hibernate 5.3.7) Я пытался отладить, печатая состояние транзакции, которое показывает, что транзакция активна.

Обратите внимание: Эторабота с hibernate 4.3

javax.persistence.TransactionRequiredException: Executing an update/delete query
    at org.hibernate.query.internal.AbstractProducedQuery.executeUpdate(AbstractProducedQuery.java:1586) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at com.rms.jobqueue.JobQueueImpl$1.doInTransaction(JobQueueImpl.java:184) ~[classes/:?]
    at com.rms.jobqueue.JobQueueImpl$1.doInTransaction(JobQueueImpl.java:1) ~[classes/:?]
    at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) ~[spring-tx-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    at com.rms.jobqueue.JobQueueImpl.markQueueAsProcessing(JobQueueImpl.java:167) ~[classes/:?]
    at com.rms.jobqueue.JobQueueImpl.dequeueIfReady(JobQueueImpl.java:229) ~[classes/:?]
    at com.rms.jobqueue.JobQueueImpl.handleJobStageChange(JobQueueImpl.java:616) ~[classes/:?]
    at com.rms.subscribe.subscriber.JobQueueStateSubscriber.handleEvent(JobQueueStateSubscriber.java:18) ~[classes/:?]
    at com.rms.subscribe.publisher.EventDispatcher.notifySubscriberSynchronously(EventDispatcher.java:75) ~[classes/:?]
    at com.rms.subscribe.publisher.SynchronousPublisherImpl.broadcast(SynchronousPublisherImpl.java:96) ~[classes/:?]
    at com.rms.event.RmsEventListener.onReceivingEntityEvent(RmsEventListener.java:35) ~[classes/:?]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_161]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_161]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_161]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_161]

Вот пример кода, который вызывает проблему: -

public boolean markQueueAsProcessing(Job qj) {

        return txTemplate.execute(new TransactionCallback<Boolean>() {
            @Override
            public Boolean doInTransaction(TransactionStatus transactionStatus) {


                String hql = "UPDATE Job qj SET qj.stage = :targetStage, qj.stageChangeDate = :stageChangeDate WHERE qj.stage = :requiredStage AND qj.id = :qjId";

                Date now = new Date();

                System.out.println("Current Transaction Status => " + TransactionSynchronizationManager.isActualTransactionActive());


                boolean processingSuccess = sessionFactory.getCurrentSession().createQuery(hql)
                        .setParameter("targetStage", QueStage.PROCESSING.name())
                        .setParameter("requiredStage", QueStage.QUEUED.name())
                        .setParameter("qjId", qj.getId())
                        .setParameter("stageChangeDate", now)
                        .executeUpdate() > 0;

                if (processingSuccess) {
                    qj.setStageChangeDate(now);
                    qj.setStage(QueStage.PROCESSING.name());
                }

                return processingSuccess;
            }
        });


    }

Файл Hibernate Cfg: -

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.temp.use_jdbc_metadata_defaults">false</property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
        <property name="hibernate.format_sql">false</property>
        <property name="hibernate.show_sql">false</property>
        <property name="hibernate.max_fetch_depth">3</property>

        <property name="hibernate.cache.use_second_level_cache">true</property>

        <property name="hibernate.cache.use_query_cache">true</property>
        <property name="hibernate.cache.region.factory_class">org.hibernate.cache.jcache.JCacheRegionFactory</property>
        <property name="hibernate.javax.cache.provider">org.ehcache.jsr107.EhcacheCachingProvider</property>

        <!--<property name="hibernate.cache.default_cache_concurrency_strategy">read-write</property>-->
        <!--<property name="hibernate.javax.cache.uri">file:///C:/Dropbox/nnooka/RMS/RMSv2/src/main/resources/ehcache.xml</property>-->

        <property name="hibernate.connection.CharSet">utf8</property>
        <property name="hibernate.connection.characterEncoding">utf8</property>
        <property name="hibernate.connection.useUnicode">true</property>

        <property name="hibernate.jdbc.batch_size">30</property>
        <property name="hibernate.order_inserts">true</property>
        <property name="hibernate.order_updates">true</property>
        <property name="hibernate.jdbc.batch_versioned_data">true</property>
        <property name="hibernate.allow_update_outside_transaction">true</property>


        <!-- <property name="hibernate.generate_statistics">true</property> -->

    </session-factory>
</hibernate-configuration>

Вот конфигурация Spring xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:jdbc="http://www.springframework.org/schema/jdbc" 
    xmlns:mvc="http://www.springframework.org/schema/mvc" 
    xmlns:context="http://www.springframework.org/schema/context"  
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:tx="http://www.springframework.org/schema/tx" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop.xsd" >


    <bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
        <property name="poolName" value="RmsHikariCP" />
        <property name="registerMbeans" value="true"/>
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />

        <property name="jdbcUrl" value="jdbc:mysql://xxxx:3306/apt_db?autoReconnect=true&amp;zeroDateTimeBehavior=convertToNull&amp;useUnicode=true&amp;characterEncoding=utf-8" />
        <property name="username" value="xxxxx"/>
        <property name="password" value="hz6yJJas"/>



        <property name="maximumPoolSize" value="180"/>
        <property name="minimumIdle" value="30"/>
        <property name="idleTimeout" value="300000"/>
        <property name="connectionTimeout" value="120000"/>
        <property name="leakDetectionThreshold" value="600000"/>

    </bean>


    <bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
        <constructor-arg ref="hikariConfig" />
    </bean>


    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="packagesToScan">
            <list>
                <value>com.rms.model</value>
            </list>
        </property>
        <property name="configLocation" value="classpath:hibernate.cfg.xml" />
    </bean>

    <!-- A transaction manager for working with Hibernate SessionFactories -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean

    </bean>


    <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
        <property name="transactionManager" ref="transactionManager"></property>
        <property name="isolationLevelName" value="ISOLATION_READ_COMMITTED"/>
    </bean>


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