spring @Transactional没有为rollbackFor = Exception.class回滚

时间:2014-04-29 12:28:41

标签: java spring-transactions

如果方法solrJ.indexAllergenBulkSlor()中发生任何异常,我需要回滚事务,但它没有回滚事务。我也将AUTOCOMMIT设置为false。请提示帮助。提前谢谢。 这就是我的服务impl看起来的样子

@Service("mcareService")
@Transactional(readOnly = true, value = "oltpTransactionManager")
public class MyServiceImpl implements MyService {

    @Override
    @Transactional(value = "oltpTransactionManager",  propagation=Propagation.REQUIRED, rollbackFor={Exception.class, SolrServerException.class})
    public boolean saveAllergens(List<AllergenAutoCmp> allergenList) {
        boolean flag = false;
        LOGGER.info("Inside saveAllergens in MCareServiceImpl");
        try {
            allergenAutoCmpRepository.deleteAllergens();
            allergenAutoCmpRepository.saveAllergens(allergenList);
            solrJ.indexAllergenBulkSlor();
            flag = true;
        } catch (SolrServerException e) {
            LOGGER.error("Error occured while solr indexing Allergens", e);
        } catch (IOException e) {
            LOGGER.error("Error occured while solr indexing Allergens", e);
        }
        LOGGER.info("returning from saveAllergens in MCareServiceImpl");
        return flag;
    }

}

2 个答案:

答案 0 :(得分:5)

这是因为您捕获了SolrServerException或IOException,但是您没有将其丢弃。如果您了解@Transational如何工作,您将意识到它包装了您的函数周围的代码并尝试捕获RuntimeException。您需要将异常传递给外层。

 try {
        allergenAutoCmpRepository.deleteAllergens();
        allergenAutoCmpRepository.saveAllergens(allergenList);
        solrJ.indexAllergenBulkSlor();
        flag = true;
    } catch (SolrServerException e) {
        LOGGER.error("Error occurred while solr indexing Allergens", e);
        throw new RuntimeException("SolrServerException occurred! Rollback my transaction.");
    } catch (IOException e) {
        LOGGER.error("Error occured while solr indexing Allergens", e);
        throw new RuntimeException("IOException occurred! Rollback my transaction.");
    }

答案 1 :(得分:2)

按照建议修改了代码,但仍然没有回滚。

所以而不是

@Override
@Transactional(value = "oltpTransactionManager",  propagation=Propagation.REQUIRED, rollbackFor={Exception.class, SolrServerException.class})
public boolean saveAllergens(List<AllergenAutoCmp> allergenList) {
    boolean flag = false;
    LOGGER.info("Inside saveAllergens in MCareServiceImpl");
    try {
        allergenAutoCmpRepository.deleteAllergens();
        allergenAutoCmpRepository.saveAllergens(allergenList);
        solrJ.indexAllergenBulkSlor();
        flag = true;
    } catch (SolrServerException e) {
        LOGGER.error("Error occured while solr indexing Allergens", e);
    } catch (IOException e) {
        LOGGER.error("Error occured while solr indexing Allergens", e);
    }
    LOGGER.info("returning from saveAllergens in MCareServiceImpl");
    return flag;
}

使用下面的一个(删除try catch)

@Override
@Transactional(value = "oltpTransactionManager",  propagation=Propagation.REQUIRED, rollbackFor={Exception.class, SolrServerException.class})
public boolean saveAllergens(List<AllergenAutoCmp> allergenList) {
    boolean flag = false;
    LOGGER.info("Inside saveAllergens in MCareServiceImpl");
        allergenAutoCmpRepository.deleteAllergens();
        allergenAutoCmpRepository.saveAllergens(allergenList);
        solrJ.indexAllergenBulkSlor();
        flag = true;
    LOGGER.info("returning from saveAllergens in MCareServiceImpl");
    return flag;
}

从控制器调用

@RequestMapping(method = RequestMethod.POST)
@ResponseBody
public boolean handleFileUpload(
        @ModelAttribute("uploadFile") MultipartFile uploadFile,
        @ModelAttribute("fileType") String fileType) throws Exception {

    LOGGER.info("inside handleFileUpload");

    CommonsMultipartFile aFile = (CommonsMultipartFile) uploadFile;
    boolean flag = false;
    if (aFile != null && aFile.getSize() > 0) {
        flag = macareService.isFileUploaded(fileType, aFile);
    }
    LOGGER.info("exiting handleFileUpload");
    return flag;
}

和调用saveAllergens(..)方法的服务方法是

@Override
public boolean isFileUploaded(String fileType, CommonsMultipartFile aFile) {
    boolean flag = false;

    try {
        if (MCareConstants.ALLERGEN_UPLOAD_FILETYPE.equals(fileType)) {
            ArrayList<AllergenAutoCmp> bulkInsertList = (ArrayList<AllergenAutoCmp>) ExcelUtils
                    .getBulkInsert(fileType, aFile);
            if (bulkInsertList.size() > 0) {
                flag = saveAllergens(bulkInsertList);
            }
        }
        if (MCareConstants.REACTION_UPLOAD_FILETYPE.equals(fileType)) {
            ArrayList<ReactionAutoCmp> bulkInsertList = (ArrayList<ReactionAutoCmp>) ExcelUtils
                    .getBulkInsert(fileType, aFile);
            if (bulkInsertList.size() > 0) {
                flag = saveReactionAutoCmps(bulkInsertList);
            }
        }
        if (MCareConstants.LABTESTS_UPLOAD_FILETYPE.equals(fileType)) {
            ArrayList<LabTestAutoCmp> bulkInsertList = (ArrayList<LabTestAutoCmp>) ExcelUtils
                    .getBulkInsert(fileType, aFile);
            if (bulkInsertList.size() > 0) {
                flag = saveLabTestAutoCmps(bulkInsertList);
            }
        }
        if (MCareConstants.STAFF_UPLOAD_FILETYPE.equals(fileType)) {
            ArrayList<StaffSolrForm> bulkInsertList = (ArrayList<StaffSolrForm>) ExcelUtils
                    .getBulkInsert(fileType, aFile);
            if (bulkInsertList.size() > 0) {
                flag = updateStaffList(bulkInsertList);
            }
        }
        if (MCareConstants.REFERRAL_DOCTOR_UPLOAD_FILETYPE.equals(fileType)) {
            ArrayList<ReferralAutoLookup> bulkInsertList = (ArrayList<ReferralAutoLookup>) ExcelUtils
                    .getBulkInsert(fileType, aFile);
            if (bulkInsertList.size() > 0) {
                flag = saveAllReferralAutolookup(bulkInsertList);
            }
        }
    } catch (HeaderNameNotFoundException e) {
        LOGGER.error("Error occured while updating solr indexing");
    } catch (MandatoryValueNotFoundException e) {
        LOGGER.error("Error occured while updating solr indexing");
    }catch (SolrServerException e) {
        LOGGER.error("Error updating index : ", e);
    }catch (IOException e) {
        LOGGER.error("Error updating index : ", e);
    }catch (Exception e) {
        LOGGER.error("Error occured while saving and solr indexing     ReactionAutoCmps", e);
    }
    return flag;
}

,日志如下

2014-04-29 19:14:21 ERROR MCareServiceImpl:405 - Error updating index : 
org.apache.solr.client.solrj.SolrServerException: Server refused connection at: http://samplename.com:8090/solr/icd102
    at org.apache.solr.client.solrj.impl.HttpSolrServer.request(HttpSolrServer.java:432)
    at org.apache.solr.client.solrj.impl.HttpSolrServer.request(HttpSolrServer.java:221)
    at org.apache.solr.client.solrj.request.AbstractUpdateRequest.process(AbstractUpdateRequest.java:105)
    at org.apache.solr.client.solrj.SolrServer.deleteByQuery(SolrServer.java:293)
    at org.apache.solr.client.solrj.SolrServer.deleteByQuery(SolrServer.java:278)
    at com.bluecapmobile.helper.SolrJ.indexAllergenBulkSlor(SolrJ.java:222)
    at com.bluecapmobile.service.impl.MCareServiceImpl.saveAllergens(MCareServiceImpl.java:103)
    at com.bluecapmobile.service.impl.MCareServiceImpl.isFileUploaded(MCareServiceImpl.java:369)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    2014-04-29 19:14:24.469 [http-bio-8080-exec-4] DEBUG o.s.o.jpa.JpaTransactionManager - Initiating transaction commit
2014-04-29 19:14:24.469 [http-bio-8080-exec-4] DEBUG o.s.o.jpa.JpaTransactionManager - Committing JPA transaction on EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@3031bb69]
2014-04-29 19:14:24 DEBUG AbstractTransactionImpl:175 - committing
2014-04-29 19:14:24 DEBUG AbstractFlushingEventListener:149 - Processing flush-time cascades
2014-04-29 19:14:24 DEBUG AbstractFlushingEventListener:189 - Dirty checking collections
2014-04-29 19:14:24 DEBUG AbstractFlushingEventListener:123 - Flushed: 0 insertions, 0 updates, 0 deletions to 3 objects
2014-04-29 19:14:24 DEBUG AbstractFlushingEventListener:130 - Flushed: 0 (re)creations, 0 updates, 0 removals to 0 collections
2014-04-29 19:14:24 DEBUG EntityPrinter:114 - Listing entities:
2014-04-29 19:14:24 DEBUG EntityPrinter:121 - com.bluecapmobile.domain.oltp.AllergenAutoCmp{alergen=Wheat, allergenId=472, description=Description, type=Food}
2014-04-29 19:14:24 DEBUG EntityPrinter:121 - com.bluecapmobile.domain.oltp.AllergenAutoCmp{alergen=Soy, allergenId=473, description=Description 1, type=Food}
2014-04-29 19:14:24 DEBUG EntityPrinter:121 - com.bluecapmobile.domain.oltp.AllergenAutoCmp{alergen=test, allergenId=474, description=test, type=test}
2014-04-29 19:14:24 DEBUG JdbcTransaction:113 - committed JDBC Connection
2014-04-29 19:14:24 DEBUG JdbcTransaction:126 - re-enabling autocommit
2014-04-29 19:14:24 DEBUG LogicalConnectionImpl:212 - Aggressively releasing JDBC connection
2014-04-29 19:14:24 DEBUG LogicalConnectionImpl:246 - Releasing JDBC connection
2014-04-29 19:14:24 DEBUG LogicalConnectionImpl:264 - Released JDBC connection
2014-04-29 19:14:24.496 [http-bio-8080-exec-4] DEBUG o.s.o.jpa.JpaTransactionManager - Closing JPA EntityManager [org.hibernate.jpa.internal.EntityManagerImpl@3031bb69] after transaction
2014-04-29 19:14:24.497 [http-bio-8080-exec-4] DEBUG o.s.o.j.EntityManagerFactoryUtils - Closing JPA EntityManager

这是我的transacton manager配置的样子

@Bean ( name = "mtdmEntityManger" )
public LocalContainerEntityManagerFactoryBean configureMtdmEntityManagerFactory ()
{
    LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean ();
    entityManagerFactoryBean.setPackagesToScan ( "com.sample.domain.mtdm" );
    entityManagerFactoryBean.setPersistenceProviderClass ( HibernatePersistenceProvider.class );

    Properties jpaProterties = new Properties ();
    jpaProterties.put ( Environment.DIALECT, dialect );
    jpaProterties.put ( Environment.FORMAT_SQL, formatSql );
    jpaProterties.put ( Environment.GENERATE_STATISTICS, true );
    jpaProterties.put ( Environment.HBM2DDL_AUTO, hbm2ddlAuto );
    jpaProterties.put ( "hibernate.ejb.naming_strategy", hibernateNamingStrategy );
    jpaProterties.put ( Environment.SHOW_SQL, showSql );
    jpaProterties.put ( Environment.FORMAT_SQL, formatSql );
    jpaProterties.put ( Environment.RELEASE_CONNECTIONS, connectionReleaseStrategy );
    jpaProterties.put ( Environment.DIALECT, dialect );
    jpaProterties.put ( Environment.DATASOURCE, dataSourceMtdm );
    jpaProterties.put ( Environment.AUTOCOMMIT, false );
    entityManagerFactoryBean.setJpaProperties ( jpaProterties );

    return entityManagerFactoryBean;
}

@Bean ( name = "mtdmTransactionManager" )
public PlatformTransactionManager annotationMtdmDrivenTransactionManager ()
{
    JpaTransactionManager mtdmTransactionManager = new JpaTransactionManager ();
    mtdmTransactionManager.setEntityManagerFactory ( configureMtdmEntityManagerFactory ().getObject () );
    return mtdmTransactionManager;
}