如何解决春季批处理中没有任何交易

时间:2018-12-28 16:26:56

标签: spring spring-batch

当我尝试在春季批处理中使用作业处理器持久保存从数据库中的csv文件恢复的某些数据时,此错误会出现在控制台中,因为我使用的是休眠

我已经尝试了两种方法,但同样存在问题!

第一:

    Session session = factory.getCurrentSession();
    session.saveOrUpdate(p);

秒:

    Session session = factory.openSession();
    session.beginTransaction();
    session.save(p);
    session.getTransaction().commit();
    session.close();
我的spring xml配置中的

数据源: 我在https://pastebin.com/RZPr1GKL

上的所有spring xml配置
<bean name="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/yassir" />
        <property name="username" value="root" />
        <property name="password" value="" />
    </bean>


    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="annotatedClasses">
            <list>
                <value>tp.entities.Personne</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
    </bean>


    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <tx:annotation-driven />

错误: javax.persistence.TransactionRequiredException:没有事务在进行中 在org.hibernate.internal.SessionImpl.checkTransactionNeeded(SessionImpl.java:3450)     在org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1418)     在org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1414)     ...

2 个答案:

答案 0 :(得分:1)

您已将Spring Batch配置为使用DataSourceTransactionManager驱动交易。该事务管理器对您的Hibernate上下文一无所知。您需要使用HibernateTransactionManager来使编写器中的Hibernate Session参与Spring Batch管理的事务。

我还建议您使用HibernateItemWriter而不是创建自定义编写器(PersonneWriter)并手动创建会话和管理交易。

可以在这里找到类似的问题/答案:Spring Batch JpaItemWriter vs HibernateItemWriter and why HibernateTransactionManager is needed when HibernateItemWriter is used

希望这会有所帮助。

答案 1 :(得分:0)

当我们在 spring boot 项目中使用 spring 批处理特别是 tasklet 时,@EnableBatchProcessing 注释将为其默认表创建自己的事务(Spring Batch Transactions)。 因此,如果您想在应用程序表(实际表执行 CRUD)中执行任何插入、更新或删除。我们必须明确提及 JpaTransactionManager 而不是默认的 spring 批处理事务。

@Configuration
@EnableBatchProcessing
public class MyJob extends DefaultBatchConfigurer {
       
       @Autowired
       private DataSource dataSource;

       @Bean
       @Primary
       public JpaTransactionManager jpaTransactionManager() {
            final JpaTransactionManager tm = new JpaTransactionManager();
            tm.setDataSource(dataSource);
            return tm;
       }
}

@Primary 是最重要的一个,否则将加载两个事务管理器。在您的工作中提及 jpaTransactionManager()

return stepBuilderFactory.get("stepOne")
                .transactionManager(jpaTransactionManager())
                .<DetailDTO,DetailDTO>chunk(100)
                .reader(reportReader) 
                .processor(reportProcessor)
                .writer(reportWriter)
                .build();

我得到的错误 - Caused by: javax.persistence.TransactionRequiredException: no transaction is in progress

如果这对您有用,请点击向上投票。