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; } }