Spring事务注释不会回滚

时间:2013-10-31 09:03:44

标签: spring annotations transactional

首先,我怀疑这是我的事务配置问题,所以我创建了一个简单的spring-jdbc项目,具有相同的事务配置,它工作正常,然后我检查日志并找出它可能与“< strong> BeanPostProcessor “,请参阅下面的日志,我花了很多时间在这上面,但没有运气,任何帮助都会非常感谢,提前感谢。

INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Bean 'securityManager' of type [class org.apache.shiro.web.mgt.DefaultWebSecurityManager] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Bean 'configAuthorizationAttributeSourceAdvisor' of type [class org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Bean 'transactionAttributeSource' of type [class org.springframework.transaction.annotation.AnnotationTransactionAttributeSource] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Bean 'transactionInterceptor' of type [class org.springframework.transaction.interceptor.TransactionInterceptor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Bean 'org.springframework.transaction.config.internalTransactionAdvisor' of type [class org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO : com.mchange.v2.log.MLog - MLog clients using log4j logging.
INFO : com.mchange.v2.c3p0.C3P0Registry - Initializing c3p0-0.9.1.2 [built 21-May-2007 15:04:56; debug? true; trace: 10]
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Bean 'dataSource' of type [class com.mchange.v2.c3p0.ComboPooledDataSource] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Bean 'jdbcTemplate' of type [class org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Bean 'fileStoreConfig' of type [class com.myapp.config.FileStoreConfig$$EnhancerByCGLIB$$e05149b7] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Bean 'pictureStorage' of type [class com.myapp.core.data.S3FileStorage] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Bean 'userDao' of type [class com.myapp.account.dao.UserDao] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Bean 'ticketDao' of type [class com.myapp.common.dao.TicketDao] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Bean 'ticketService' of type [class com.myapp.common.service.impl.TicketServiceImpl] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Bean 'imageDao' of type [class com.myapp.common.dao.ImageDao] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Bean 'imageService' of type [class com.myapp.common.service.impl.ImageServiceImpl] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
INFO : org.springframework.web.context.support.AnnotationConfigWebApplicationContext - Bean 'mailConfig' of type [class com.myapp.config.MailConfig$$EnhancerByCGLIB$$196df0ef] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)

添加我的应用配置

AppConfig.java

@Configuration
@ComponentScan(basePackages = {"com.myapp.account.web", "com.myapp.account.interceptor", "com.myapp.account.security", "com.myapp.common.web", "com.myapp.email"})
@PropertySource(value = {"classpath:config.properties", "classpath:app.properties"})
public class AppConfig {


}

DataConfig.java

@Configuration
@ComponentScan(basePackages = {"com.myapp.account.service", "com.myapp.account.dao", "com.myapp.common.service", "com.myapp.common.dao"}) // Specifies which package to scan
@EnableTransactionManagement
public class DataConfig {

    @Inject
    private Environment environment;

    @Bean(destroyMethod="close")
    public ComboPooledDataSource dataSource() throws PropertyVetoException {
        ComboPooledDataSource cpds = new ComboPooledDataSource();
        cpds.setDriverClass(environment.getProperty("jdbc.driverClassName"));
        cpds.setJdbcUrl(environment.getProperty("jdbc.url"));
        cpds.setUser(environment.getProperty("jdbc.username"));
        cpds.setPassword(environment.getProperty("jdbc.password"));
        cpds.setInitialPoolSize(environment.getProperty("jdbc.initialPoolSize", Integer.class));
        cpds.setMinPoolSize(environment.getProperty("jdbc.minPoolSize", Integer.class));
        cpds.setMaxPoolSize(environment.getProperty("jdbc.maxPoolSize", Integer.class));
        cpds.setCheckoutTimeout(environment.getProperty("jdbc.checkoutTimeout", Integer.class));
        cpds.setMaxIdleTime(environment.getProperty("jdbc.maxIdleTime", Integer.class));
        cpds.setIdleConnectionTestPeriod(environment.getProperty("jdbc.idleConnectionTestPeriod", Integer.class));
        cpds.setAcquireIncrement(environment.getProperty("jdbc.acquireIncrement", Integer.class));
        return cpds;
    }

    @Bean
    public NamedParameterJdbcTemplate jdbcTemplate() throws PropertyVetoException {
        return new NamedParameterJdbcTemplate(dataSource());
    }

    /**
     * Allows transactions to be managed against the RDBMS using the JDBC API.
     * @throws PropertyVetoException 
     */
    @Bean
    public PlatformTransactionManager transactionManager() throws PropertyVetoException {
        return new DataSourceTransactionManager(dataSource());
    }

    /**
    @Bean
    public DataSourceTransactionManager transactionManager() throws PropertyVetoException {
        return new DataSourceTransactionManager(dataSource());
    }
    */

    @Bean
    public UserDao userDao() throws PropertyVetoException {
        return new UserDao(jdbcTemplate());
    }

    @Bean
    public TicketDao ticketDao() throws PropertyVetoException {
        return new TicketDao(jdbcTemplate());
    }

}

SecurityConfig.java

@Configuration
public class SecurityConfig {

    @Bean
    public Realm configureShiroOAuthDbRealm() {
        return new ShiroOAuthDbRealm();
    }

    @Bean(name = "ehCacheManager")
    public EhCacheManager configCacheManager() {
        return new EhCacheManager();
    }

    @Bean(name = "securityManager")
    public DefaultWebSecurityManager configSecurityManager() {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        ArrayList<Realm> realms = new ArrayList<Realm>();
        realms.add(configureShiroPasswordDbRealm());
        realms.add(configureShiroTicketDbRealm());
        realms.add(configureShiroOAuthDbRealm());
        securityManager.setRealms(realms);
        securityManager.setCacheManager(configCacheManager());
        return securityManager;
    }

    @Bean(name = "lifecycleBeanPostProcessor")
    public LifecycleBeanPostProcessor configLifecycleBeanPostProcessor() {
        LifecycleBeanPostProcessor lifecycleBeanPostProcessor = new LifecycleBeanPostProcessor();
        return lifecycleBeanPostProcessor;
    }

    /**
     * Enable Shiro Annotations for Spring-configured beans.
     * Only run after the lifecycleBeanProcessor has run.
     */
    @Bean
    public DefaultAdvisorAutoProxyCreator configDefaultAdvisorAutoProxyCreator() {
        return new DefaultAdvisorAutoProxyCreator();
    }

    @Bean
    public AuthorizationAttributeSourceAdvisor configAuthorizationAttributeSourceAdvisor() {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(configSecurityManager());
        return authorizationAttributeSourceAdvisor;
    }

    @Bean(name = "shiroFilter")
    public ShiroFilterFactoryBean configShiroFilterFactoryBean() {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(configSecurityManager());
        shiroFilterFactoryBean.setLoginUrl("/login");
        shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");
        shiroFilterFactoryBean.setSuccessUrl("/");
        Map<String, javax.servlet.Filter> filters = new HashMap<String, javax.servlet.Filter>();
        filters.put("authc", new PassThruAuthenticationFilter());
        shiroFilterFactoryBean.setFilters(filters);
        Map<String, String> filterChainDefinitionMap = new HashMap<String, String>();
        filterChainDefinitionMap.put("/control_panel/**", "authc, roles[administrator]");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return shiroFilterFactoryBean;
    }
}

UserController.java(来自userService的调用测试方法 testTransaction

@Controller
public class UserController {

    private static final Logger logger = LoggerFactory.getLogger(UserController.class);

    @Resource(name="userService")
    protected UserService userService;

    @Resource(name="ticketService")
    protected TicketService ticketService;

    @RequestMapping(value = "/test-transaction", method = RequestMethod.GET)
    public String testTransaction(Model model, HttpServletRequest request) throws Exception {
        try{
            User user = new User();
            user.setUsername("test.transaction");
            userService.testTransaction(user);
        }catch(Exception e) {
            logger.error(e.getMessage(), e);
            throw e;
        }
        return "redirect:/";
    }

}

UserServiceImpl.java( testTransaction 抛出RuntimeException的测试方法)

@Service("userService")
public class UserServiceImpl implements UserService {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    @Resource
    private UserDao userDao;

    @Resource
    private TicketService ticketService;

    @Transactional
    public void testTransaction(User user) throws SystemException {
        userDao.add(user);
        Long.valueOf("Throw RuntimeException");
    }
}

UserDao.java

public class UserDao extends BaseDao {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public UserDao(NamedParameterJdbcTemplate jdbcTemplate) {
        super(jdbcTemplate);
    }

    private static final String ADD = "INSERT INTO user_(username, email, password_, create_date, modified_date, status_) VALUES(:username, :email, :password, :createDate, :modifiedDate, :status)";

    public long add(User user) throws SystemException {
        try{
            return updateForLongKey(ADD, user);
        }catch(Exception e) {
            throw processException(e);
        }
    }
}

BaseDao.java

public class BaseDao implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    protected NamedParameterJdbcTemplate jdbcTemplate;

    protected BaseDao(NamedParameterJdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    protected <T> long updateForLongKey(final String sql, T t) {
        SqlParameterSource paramSource = new BeanPropertySqlParameterSource(t);
        KeyHolder keyHolder = new GeneratedKeyHolder();
        jdbcTemplate.update(sql, paramSource, keyHolder);
        return keyHolder.getKey().longValue();
    }



    public SystemException processException(Exception e) {
        if (!(e instanceof DataAccessException)) {
            logger.error("Caught unexpected exception " + e.getClass().getName());
        }

        if (logger.isDebugEnabled()) {
            logger.debug(e.getMessage(), e);
        }

        return new SystemException(e);
    }

}

0 个答案:

没有答案