【问题标题】:how to fix no transaction is in progress in spring batch如何修复春季批处理中没有正在进行的交易
【发布时间】:2019-05-26 10:51:35
【问题描述】:

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

我已经尝试了 2 种方法,但同样的问题!

第一:

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

秒:

    Session session = factory.openSession();
    session.beginTransaction();
    session.save(p);
    session.getTransaction().commit();
    session.close();

我的 spring xml 配置中的数据源: 我所有的spring xml配置都在这里https://pastebin.com/RZPr1GKL

<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) ...

【问题讨论】:

  • 1.由于您使用的是 Hibernate,因此您应该使用 HibernateTransactionManager。 2. 由于您使用的是基于注解的事务,因此应该是事务性的 bean 方法应该使用@Transactional 进行注解。 docs.spring.io/spring/docs/current/spring-framework-reference/…
  • 我添加了注释@Transactional public void savePersonne(Personne p) { Session session = factory.getCurrentSession(); session.saveOrUpdate(p); } 但问题仍然存在
  • 好吧,显然您阅读了我评论的第二部分,但没有阅读第一部分。
  • 如何使用 HibernateTransactionManager。 ?
  • 如我在第一条评论中发布的链接所示。

标签: spring spring-batch


【解决方案1】:

当我们在spring boot项目中使用spring batch特别是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

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

【讨论】:

  • 还是同样的问题 javax.persistence.TransactionRequiredException: org.hibernate.internal.SessionImpl.checkTransactionNeeded(SessionImpl.java:3466) 没有事务正在进行中~[hibernate-core-5.2.16.Final .jar:5.2.16.Final] 在 org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1426) ~[hibernate-core-5.2.16.Final.jar:5.2.16.Final] 在 org.hibernate .internal.SessionImpl.flush(SessionImpl.java:1422) ~[hibernate-core-5.2.16.Final.jar:5.2.16.Final]
【解决方案2】:

您将 Spring Batch 配置为使用 DataSourceTransactionManager 来驱动事务。这个事务管理器对你的 Hibernate 上下文一无所知。您需要使用HibernateTransactionManager 使您的writer 中的Hibernate Session 参与Spring Batch 托管事务。

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

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

希望这会有所帮助。

【讨论】:

  • 感谢当我使用 HibernateTransactionManager 它工作:
  • 所以我们只需要创建 bean,rest spring 会处理吗?还是我们需要在运行作业时指定它
  • @user124 创建事务管理器 bean 是不够的。如果要使用自定义事务管理器,则需要提供 BatchConfigurer bean 并覆盖 getTransactionManager 以返回您的事务管理器,请参阅:docs.spring.io/spring-batch/docs/4.3.x/reference/html/…
  • 但是你在答案中提到的链接,它在配置step byt .transactionManager(tManager)时提供了事务管理器,它没有像你说的那样覆盖BatchConfigurer?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-15
相关资源
最近更新 更多