1. 程式人生 > >spring多執行緒事物解決辦法

spring多執行緒事物解決辦法

1、最近做專案使用了多線,但是發現多執行緒事務無法起作用,就是多執行緒執行時每個執行緒的方法雖然加了事務的註解但是資料插入依舊不會回滾

2、此時主執行緒操作資料插入事物是起作用的。

springboot 解決辦法

    先獲取spring的context

    配置中 新增事物管理器1

package luculent.fupin.tools;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class SpringUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext = null;

    @Override

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException{

        if (SpringUtil.applicationContext == null) {

            SpringUtil.applicationContext = applicationContext;

        }
    }

    // 獲取applicationContext

    public static ApplicationContext getApplicationContext(){

        return applicationContext;

    }

    // 通過name獲取 Bean.

    public static Object getBean(String name){

        return getApplicationContext ().getBean (name);

    }

    // 通過class獲取Bean.

    public static <T> T getBean(Class<T> clazz){

        return getApplicationContext ().getBean (clazz);

    }

    // 通過name,以及Clazz返回指定的Bean

    public static <T> T getBean(String name,Class<T> clazz){

        return getApplicationContext ().getBean (name, clazz);

    }

}
import java.util.Properties;

import javax.sql.DataSource;

import org.springframework.boot.bind.RelaxedPropertyResolver;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.orm.hibernate4.HibernateTemplate;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.alibaba.druid.pool.DruidDataSource;

@Configuration
@EnableTransactionManagement
public class DruidDataSourceConfiguration implements EnvironmentAware {

    private RelaxedPropertyResolver propertyResolver;

    @Override
    public void setEnvironment(Environment env){
        this.propertyResolver = new RelaxedPropertyResolver (env,"spring.hibernate.");
    }

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource druidDataSource(){
        DruidDataSource druidDataSource = new DruidDataSource (); 
        return druidDataSource;
    }

    
    
    
    @Bean
    public LocalSessionFactoryBean sessionFactory(){
        LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean ();
        sessionFactory.setDataSource (this.druidDataSource ());
        sessionFactory.setPackagesToScan (new String[] { "luculent.fastb" });
        
        sessionFactory.setHibernateProperties (hibernateProperties ());
        return sessionFactory;
    }

    // 建立事務管理器1
    @Bean(name = "transactionManager")
    public PlatformTransactionManager txManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }
    
    @Bean
    public HibernateTemplate hibernateTemplate(){
        HibernateTemplate temp = new HibernateTemplate ();
        temp.setSessionFactory (this.sessionFactory ().getObject ());
        return temp;
    }

    @Bean
    public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
        return new PersistenceExceptionTranslationPostProcessor ();
    }

    Properties hibernateProperties(){
        return new Properties () {

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

            {  
                setProperty ("show_sql", propertyResolver.getProperty ("show_sql"));
                setProperty ("current_session_context_class", propertyResolver.getProperty ("current_session_context_class"));
            }
        };
    }
}


獲取 

jdbcTemplate

transactionManager

用自己寫的事物替代

package luculent.fupin.runable;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Import;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import luculent.fupin.tools.SpringUtil;


@Import(value = { SpringUtil.class })
public class PlatformInitiative{
	
	private static final Logger logger = LoggerFactory.getLogger(PlatformInitiative.class);
	
	private static JdbcTemplate jdbcTemplate = (JdbcTemplate) SpringUtil.getBean ("jdbcTemplate");

	private static DataSourceTransactionManager transactionManager ;
	private static DefaultTransactionDefinition definition;
	
	static{//初始化 DefaultTransactionDefinition
		//WebApplicationContext webctx = ContextLoader.getCurrentWebApplicationContext();
		definition = new DefaultTransactionDefinition();
		definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
		definition.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
		transactionManager = (DataSourceTransactionManager) SpringUtil.getBean ("transactionManager");
	} 
   
    public static boolean insert(String[] sqls){

        if (sqls != null && sqls.length > 0) {
            for ( String sql : sqls ) {
            	return insert(sql);
            }
        }
        return false;
    }
    public static boolean insert(String sql){
   	 
		boolean saveFlag = false;
		TransactionStatus transactionStatus = (TransactionStatus) transactionManager.getTransaction(definition);
		try {
    		int rId =  jdbcTemplate.update (sql);
    		if(rId > 0){
				 saveFlag = true;
			 }
		} catch (Exception e) { 
			logger.error("platformInitiativeHessian-save: -error",e);
		}
    	if(saveFlag ){
    		transactionManager.commit(transactionStatus);
    	}else{
    		transactionManager.rollback(transactionStatus);
    	}
		return saveFlag;
	}
	 
	 
	public static boolean insertBatch(String[] sqls){
	 
		boolean saveFlag = false;
		TransactionStatus transactionStatus = (TransactionStatus) transactionManager.getTransaction(definition);
		try {
    		int[] ides = jdbcTemplate.batchUpdate (sqls);
    		if(ides != null && ides.length > 0){
				 saveFlag = true;
			 }
		} catch (Exception e) { 
			logger.error("platformInitiativeHessian-save: -error",e);
		}
    	if(saveFlag ){
    		transactionManager.commit(transactionStatus);
    	}else{
    		transactionManager.rollback(transactionStatus);
    	}
		return saveFlag;
	}
	
	public static boolean update(String upState,String state,String id){
		
		boolean saveFlag = false;
		TransactionStatus transactionStatus = (TransactionStatus) transactionManager.getTransaction(definition);
		try {
			 int rId = jdbcTemplate.update (upState, new Object[] { state, id });
			 if(rId > 0){
				 saveFlag = true;
			 }
		} catch (Exception e) { 
			logger.error("platformInitiativeHessian-save: -error",e);
		}
    	if(saveFlag ){
    		transactionManager.commit(transactionStatus);
    	}else{
    		transactionManager.rollback(transactionStatus);
    	}
		return saveFlag;
	} 
	
	public static boolean update(String sql, Object... args){
		
		boolean saveFlag = false;
		TransactionStatus transactionStatus = (TransactionStatus) transactionManager.getTransaction(definition);
		try {
			 int rId = jdbcTemplate.update (sql,args);
			 if(rId > 0){
				 saveFlag = true;
			 }
		} catch (Exception e) { 
			logger.error("platformInitiativeHessian-save: -error",e);
		}
    	if(saveFlag ){
    		transactionManager.commit(transactionStatus);
    	}else{
    		transactionManager.rollback(transactionStatus);
    	}
		return saveFlag;
	} 
}