处理bibernate的no transaction is in progress问题

Owen Jia 2019年02月21日 443次浏览

no transaction is in progress这个error让我烦心了好多天,找到了解决办法收录一下并贡献其他小伙伴。

环境配置

服务插件环境如下:

  • spring-data-jpa 1.10.5
  • druid 1.1.8
  • spring-boot 1.5.2
  • spring 4.3.5

配置上如下:

@Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean initFactoryBean() {
    LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
    factoryBean.setDataSource(initDurid());
    factoryBean.setJpaVendorAdapter(initHibernateJpaVendorAdapter());
    factoryBean.setPersistenceUnitName("default");
    factoryBean.setPackagesToScan("com.xxxx");
    Properties jpaProp = new Properties();
    jpaProp.setProperty("hibernate.hbm2ddl.auto",hbm2ddlAuto);
    jpaProp.setProperty("hibernate.show_sql",showSql);
    jpaProp.setProperty("hibernate.format_sql",formatSql);
    jpaProp.setProperty("hibernate.physical_naming_strategy","com.xxxx.orm.jpa.ImprovedNamingStrategy");
    //配置连接释放模式:after_statement 请求执行后释放,on_close session主动关闭释放
    jpaProp.setProperty("hibernate.connection.release_mode","after_statement");//"on_close"
    factoryBean.setJpaProperties(jpaProp);
    return factoryBean;
}
@Bean(name = "hibernateJpaVendorAdapter")
public HibernateJpaVendorAdapter initHibernateJpaVendorAdapter(){
    HibernateJpaVendorAdapter jpaVendor = new HibernateJpaVendorAdapter();
    jpaVendor.setDatabasePlatform(Hibernates.getDialect(initDurid()));
    return jpaVendor;
}

@Bean(name = "transactionManager")
public JpaTransactionManager initJapTransactionM(){
    JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
    jpaTransactionManager.setEntityManagerFactory(initFactoryBean().getNativeEntityManagerFactory());
    return jpaTransactionManager;
}

@Bean(name = "transactionTemplate")
public TransactionTemplate initTransactionTemplate(){
    TransactionTemplate transactionTemplate = new TransactionTemplate();
    transactionTemplate.setTransactionManager(initJapTransactionM());
    return transactionTemplate;
}

错误场景

一块代码一直会提示no transaction is in progress错误,如下,:

[rent] 2019-02-20 01:01:07,969 ERROR [pool-5-thread-11] com.xxxx.rent.platform.job.JobService.jobRunnerDailySettlement(110) | 账单日结算任务执行失败,nodeId:a60d4d5428e444fb95f7f3e8089556bb,contractId:22416,error:no transaction is in progress

解决办法

添加@Transactional注解,关键是在哪里添加?

看了很多网上相关的文章归集的基本思路是:jpa的hibernate要求在dao的方法上要添加事务注解。

根据业务不同去区分只读还是非只读事务注解。

    @Override
    @Autowired
    @Qualifier("TRentSettlementBillDao")
    protected void setDao(JpaDao dao) {
        super.dao = dao;
    }

    /**
     * 查找当前的未清算租金结算单-每个租赁公司只有一条记录
     */
    @Transactional(readOnly = true)
    public TRentSettlementBill findLeaseSettlementBill(Long companyId) {
        List<SearchFilter> filters = new ArrayList<>();
        filters.add(new SearchFilter("debitSide", SearchFilter.Operator.EQ, companyId));
        filters.add(new SearchFilter("debitSideType", SearchFilter.Operator.EQ, Contents.ACCOUNT_COMPANY));
        filters.add(new SearchFilter("source", SearchFilter.Operator.EQ, Contents.FEE_SOURCE_LEASE_WITHDRAW));
        filters.add(new SearchFilter("status", SearchFilter.Operator.EQ, SettlementBillStatus.TO_SUBMIT));

        return findOne(filters);
    }

经过几天的观察发现确实解决了目前的问题,总算填完了这个坑。

对于hibernate这个的原理还是要花些时间研究研究!

作者:Owen Jia

推荐关注他的博客(Owen Blog),有大量优质博文;