如何在Spring MVC中配置没有web.xml的事务

时间:2016-05-02 13:52:36

标签: java spring spring-mvc spring-transactions transactional

我在没有web.xml的情况下使用Spring MVC,因为我使用的是最后一个Spring Security配置,所以我有一个像这样的MvcConfig类:

@Configuration
@EnableTransactionManagement
@ComponentScan("com.atoutjeu")
public class MvcConfig implements TransactionManagementConfigurer {


    @Bean(name = "viewResolver")
    public InternalResourceViewResolver getViewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setPrefix("/WEB-INF/jsp/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }

    @Bean(name = "dataSource")
    public DataSource dataSource() {
        ResourceBundle dbBundle = ResourceBundle.getBundle("database");
        dbBundle.getString("db.ip");
        DriverManagerDataSource driverManagerDataSource = new TransactionalDataSource();
        driverManagerDataSource.setDriverClassName("org.postgresql.Driver");
        driverManagerDataSource.setUrl("jdbc:postgresql://"+dbBundle.getString("db.ip")+":5432/"+dbBundle.getString("db.dbname"));
        driverManagerDataSource.setUsername(dbBundle.getString("db.user"));
        driverManagerDataSource.setPassword(dbBundle.getString("db.password"));  
        return driverManagerDataSource;
    }


    @Bean(name="txManager")
    public PlatformTransactionManager transactionManager() {
        return new DataSourceTransactionManager(dataSource());
    }

    @Override
    public PlatformTransactionManager annotationDrivenTransactionManager() {
        return transactionManager();
    }

    @Bean(name = "resourceBundleViewResolver")
    public ResourceBundleViewResolver getResourceBundleViewResolver(){
        ResourceBundleViewResolver rbvr = new ResourceBundleViewResolver();
        rbvr.setOrder(0);
        rbvr.setBasename("views");
        return rbvr;
    }

    @Bean
    public PretServiceImpl pretServiceImpl() {
        // configure and return a class having @Transactional methods
        return new PretServiceImpl();
    }


}

我有一项服务:

@Service
@Transactional
public class PretServiceImpl implements IPretService {

    @Autowired
    private IAdherentDao adherentDao;

    @Autowired
    private IJeuDao jeuDao;

    @Autowired
    private IPretDao pretDao;

    @Autowired
    private IOperationDao operationDao;

    @Autowired
    private IParamLudoDao paramLudoDao;


    private Logger logger = Logger.getLogger(AdherentServiceImpl.class);

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
    public int louerPaiementDirect(int idAdherent, int idJeu, String dateSortie, String dateRetourPrevue, String commentaireSortie) throws ExceptionMetier, ExceptionTechnique {
        Adherent adherent = null;
        try {
            adherent = adherentDao.getAdherent(idAdherent);
        } catch (ExceptionTechnique e) {
            // TODO: handle exception
        }
        Jeu jeu = jeuDao.getJeu(idJeu);
        Pret pret = new Pret();
        pret.setAdherent(adherent);
        pret.setJeu(jeu);
        pret.setDateSortie(DateUtils.getDateFromDatePicker(dateSortie));
        pret.setDateRetourPrevue(DateUtils.getDateFromDatePicker(dateRetourPrevue));

        pret.setCommentaireSortie(commentaireSortie);
        int idPret = pretDao.creerPret(pret);

        //throw new RuntimeException();

        //TODO créer une opération
        Operation operation = new Operation();
        operation.setAdherent(adherent);
        operation.setDateOperation(DateUtils.getDateFromDatePicker(dateSortie));
        operation.setDateReglement(DateUtils.getDateFromDatePicker(dateSortie));
        operation.setModeReglement(paramLudoDao.getParamLudo(ModeReglement.class, "mode_reglement", ModeReglement.TIRELIRE));
        operation.setPrestation(jeu.getCategorie().getPrestation());
        operation.setMontant(operation.getPrestation().getCout());
        operation.setCredit(false);
        //operation.setTauxRemise(tauxRemise);
        operationDao.creerOperation(operation);

        adherent.setTirelire(adherent.getTirelire() - jeu.getCategorie().getPrestation().getCout());
        return idPret;
    }
//....

}

当出现异常时,我的方法louerPaiementDirect不会回滚。我不明白为什么?

2 个答案:

答案 0 :(得分:0)

是未经检查的异常(RuntimeException还是子类型)或已选中的异常。

Spring Framework的@transaction仅在运行时未经检查的异常情况下回滚。您可以通过配置中的一些更改来获取已检查异常的回滚。

答案 1 :(得分:0)

请在下面找到web.xml替代的代码

package com.candidjava.spring.configuration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import com.candidjava.spring.configuration.SpringConfiguration;
public class SpringWebIntializer implements WebApplicationInitializer {
    public void onStartup(ServletContext container) throws ServletException {
        // TODO Auto-generated method stub
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.register(SpringConfiguration.class);
        context.setServletContext(container);
        container.addListener(new ContextLoaderListener(context));
        ServletRegistration.Dynamic servlet = container.addServlet("dispatcher", new DispatcherServlet(context));
        servlet.setLoadOnStartup(1);
        servlet.addMapping("/");
    }
}

参考Spring mvc hello world example