首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring事务日志已回滚,但未回滚

Spring事务日志已回滚,但未回滚
EN

Stack Overflow用户
提问于 2017-06-20 06:00:16
回答 1查看 866关注 0票数 1

这些是我的类和配置,

ServiceImpl.java

代码语言:javascript
复制
@Override
@Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
public InsertUpdateSuccessBean insertNewSiteEntry(SiteEntry newSiteBean) throws SQLException {
    dao.insert1();
    dao.insert2();
    except();
    return new InsertUpdateSuccessBean(true,LoggerConstants.NEW_SITE_ENTRY_SUCCESS);
}
private void except()throws SQLException{
throw new SQLException();
}

DAOImpl.java

代码语言:javascript
复制
@Repository
public class DAOImpl implements DAO 
{
    @Autowired
    private DataSourceTransactionManager transManager;
    @Autowired
    private CommonDAOUtils commonUtils;
    private static final Logger logger = Logger.getLogger(HunterDAOImpl.class) ;
    @Override
    public Integer insert1() throws SQLException { 
    Integer insertNumRows = 0;
    Connection connectionObject = transManager.getDataSource().getConnection();
    PreparedStatement psObject = connectionObject.prepareStatement(
 SQLQuery );
    insertNumRows = psObject.executeUpdate();
    commonUtils.closer(null,psObject,connectionObject);
        // Function to close open connection resultsets statement objects
    return insertNumRows;
}

     @Override
    public Integer insert2() throws SQLException {
    Integer insertNumRows = 0;
    Connection connectionObject = transManager.getDataSource().getConnection();
    PreparedStatement psObject = connectionObject.prepareStatement(
 SQLQuery );
    insertNumRows = psObject.executeUpdate();
    commonUtils.closer(null,psObject,connectionObject);
        // Function to close open connection resultsets statement objects
    return insertNumRows;
}
}

AppConfig.java

代码语言:javascript
复制
import com.interceptors.AppInterceptor;
import com.utils.Constants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.*;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

@Component
@Configuration
@EnableWebMvc
@Configurable
@ComponentScan(basePackages = {Constants.BASE_PACKAGE})
@EnableAspectJAutoProxy(proxyTargetClass = true)
@PropertySource(Constants.DB_PROPERTIES_PATH)
@EnableTransactionManagement
public class AppConfig extends WebMvcConfigurerAdapter implements EnvironmentAware{

    @Autowired
    Environment environmentObject;

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer(){
        PropertySourcesPlaceholderConfigurer placeHolder =new PropertySourcesPlaceholderConfigurer();
        placeHolder.setLocation(new ClassPathResource(Constants.PROP_FILE_NAME));
        return placeHolder;
    }

    @Bean
    public InternalResourceViewResolver viewResolver(){
        InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
        internalResourceViewResolver.setPrefix(Constants.ROOT_PATH);
        internalResourceViewResolver.setSuffix(Constants.JSP_DOT_EXTENSION);
        return internalResourceViewResolver;
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }

    @Bean
    public DriverManagerDataSource dataSource(){
        DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource();
        driverManagerDataSource.setDriverClassName(environmentObject.getProperty(Constants.JDBC_DRIVERCLASS_NAME_PROP_FILE));
        driverManagerDataSource.setUrl(environmentObject.getProperty(Constants.JDBC_URL_PROP_FILE));
        driverManagerDataSource.setUsername(environmentObject.getProperty(Constants.JDBC_USERNAME_PROP_FILE));
        driverManagerDataSource.setPassword(new String(Constants.PASSWORD));
        return driverManagerDataSource;
    }

    @Bean
    public AutowiredAnnotationBeanPostProcessor postProcessorBean(){
        return new AutowiredAnnotationBeanPostProcessor();
    }



    private ClientHttpRequestFactory getClientHttpRequestFactory() {
        int timeout = 5000;
        HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();
        clientHttpRequestFactory.setConnectTimeout(timeout);
        return clientHttpRequestFactory;
    }

    @Bean
    public DataSourceTransactionManager transactionManager(){
        final DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(dataSource());
        transactionManager.setRollbackOnCommitFailure(true);
        return transactionManager;
    }
}

我也有一个关于我的项目的建议:

代码语言:javascript
复制
@Aspect
@Component
public class AroundAdvice
{
    private static final Logger logger = Logger.getLogger(AroundAdvice.class) ;
    // Add pointcuts here - package names here for around advice
    @Around("execution(* com.beans.*.*(..)) || " +
            "execution(* com.config.*.*(..)) || " +
            "execution(* com.controller.*.*(..)) || " +
            "execution(* com.dao.*.*(..)) || " +
            "execution(* com.service.*.*(..)) || " +
            "execution(* com.utils.*.*(..)) || "+
            "execution(* com.interceptors.*.*(..))")
    public Object aroundAdviceMethod(ProceedingJoinPoint proceedingObject)throws Throwable{
        MethodSignature methodSignObject = (MethodSignature) proceedingObject.getSignature();
        logger.debug(Constants.EXECUTING_METH_STR + methodSignObject.getMethod());
        Object value = null;
        try {
            value = proceedingObject.proceed();
        } catch (Exception e) {
            e.printStackTrace();
            logger.error(Constants.EXCEPTION_ASPECT_STR+methodSignObject.getMethod());
            logger.error(Constants.EXCEPTION_MESSAGE,e);
            throw e;
        }
        logger.debug(Constants.RETURN_STR+value);
        return value;
    }
}

在执行这个流时,插入是成功的,但是当异常被抛出时,它不会回滚。但是,我的日志记录器显示回滚已初始化并按如下方式完成,

代码语言:javascript
复制
14:11:51 DEBUG DataSourceTransactionManager:851 - Initiating transaction rollback
14:11:51 DEBUG DataSourceTransactionManager:325 - Rolling back JDBC transaction on Connection [org.postgresql.jdbc4.Jdbc4Connection@3b467b21]
14:11:51 DEBUG DataSourceTransactionManager:368 - Releasing JDBC Connection [org.postgresql.jdbc4.Jdbc4Connection@3b467b21] after transaction

如果我遗漏了什么,请告诉我

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-06-21 03:36:59

问题出在你的刀上。您正在自己打开连接,因此绕过了所有事务管理。你的道会变得复杂,只需使用JdbcTemplate而不是你当前的代码。

代码语言:javascript
复制
@Repository
public class DAOImpl implements DAO {
    private static final Logger logger = Logger.getLogger(HunterDAOImpl.class) ;

    private final JdbcTemplate jdbc;

    public DAOImpl(DataSource dataSource) {
        this.jdbc = new JdbcTemplate(dataSource);
    }

    @Override
    public Integer insert1() throws SQLException { 
        return jdbc.update(SQLQuery);
    }

     @Override
    public Integer insert2() throws SQLException {
        return jdbc.update(SQLQuery);
    }

}

这将与您的代码执行完全相同的操作,只有一个主要区别:它将使用在启动事务时打开的Connection。您的示例使用了3个独立的连接,因此使用了3个单独的事务,而不是1个单独的事务。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44640645

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档