首页 文章

TransactionManager和注释的Spring 3问题

提问于
浏览
2

我正在尝试在我的Web应用程序中设置一个TransactionManager(由Spring MVC 3提供支持),因为我需要一个注释为@Transactional的组件方法 .

这是我的情况:

  • web.xml:为Spring ContextLoaderListener(applicationContext.xml和database.xml)加载2个xml文件

  • applicationContext.xml:包含一些我无法通过注释定义的bean,以及注释标签,以及通常的上下文:annotation-config和context:component-scan(此组件扫描包含包含@Transactional的包方法)

  • database.xml:包含数据源(我使用的是commons-dbcp的BasicDataSource),事务管理器定义和tx:annotation-driven .

我有一个@Component(DeleteComponent),它有一个接口和一个实现(DeleteComponentImpl) . 实现类使用@Component注释,并且有一个使用@Transactional注释的公共方法(我注释了具体类而不是接口,如Spring文档所述) . 对于@Transactional我没有放任何参数,因为默认值很好 . 这个类有一些DAO(用@Repository注释)通过@Autowired注入 . 我只使用普通的JDBC(没有Hibernate或其他ORM) . 这个@Component被注入一个@Controller(在spring-servlet.xml中定义) .

如果注释为@Transactional的方法抛出异常(未选中,如RuntimeException),则不会回滚任何内容 . 数据库保留异常之前所做的更改 . 我正在使用Jetty Web服务器在本地测试我的应用程序 . 我注意到的事实上似乎没有设置事务管理器 . 实际上,我的事务管理器名为“transactionManager” . 用于设置注释驱动事务的xml行是

<tx:annotation-driven transaction-manager="transactionManager"/>

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

如果我将其更改为使用不存在的bean名称

<tx:annotation-driven transaction-manager="fake"/>

该应用程序仍然正确部署,并没有抱怨 .

有关我应该检查什么才能使其正常工作的任何提示?

谢谢 .

3 回答

  • 1

    我通过使用@Transactional(rollbackFor = RuntimeException.class)并从BasicDataSource切换到c3p0库中存在的ComboPooled来解决 . 谢谢你的建议 .

  • 2

    要在抛出异常时进行回滚,请添加:

    @Transactional(rollbackFor=Exception.class)
    

    您还需要设置transactionManger bean(这是我的,使用hibernate):

    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager" 
                    p:sessionFactory-ref="sessionFactory" />
    

    我发现这是tutorial资料 .

  • -2

    我相信Spring不会在@Component上扫描@Autowired和@Resource . 尝试使用ContextHolder类来获取上下文和DAO

    @Component
    public class ContextHolder implements ApplicationContextAware {
    
        /** 
         * Spring context which will directly be injected by Spring itself
         */
        private static ApplicationContext context = null;
    
        /**
         * Overridden method of ApplicationContextAware, which will automatically be called by the container
         */
        public void setApplicationContext(ApplicationContext context) throws BeansException {
            this.context = context;
        }
    
        /**
    
        /**
         * Static method used to get the context
         */
        public static ApplicationContext getApplicationContext() {
            return context;
        }
    }
    

    并致电你的道:

    ContextHolder.getApplicationContext().getBean("MyDAO");
    

相关问题