2016-03-21 15 views
0

私は2つの異なるデータベースを持っています。それぞれを構成し、関連するTransactionManagerをそれぞれの@Transactionalサービスで構成します。問題は、保存しようとするたびにトランザクションマネージャーの1つだけを使用しようとすることです。他のトランザクションマネージャは完全に無視されます。この2つの保存操作は、要求が受信者リストを使用してsave(Product)およびsave(User)に送信されてから、ほぼ同時に2つのSpring統合非同期プロセスで実行されることにも注意してください。これが問題の原因になりますか?私の設定が間違って何Springが同じSessionFactoryを使用していて、コンフィグレーション済みのトランザクションマネージャを無視しています

@Configuration 
    @EnableTransactionManagement 
    @ComponentScan("com.edx.db2") 
    @PropertySource(value=....) 
    public class DB2Config { 
    @Autowired 
    private Environment env; 



    @Bean 
    public UserDao UserDao(){ 
     UserDao UserDao=new UserService(); 
     return UserDao; 
    } 

    @Bean 
    @Qualifier(value="db2SessionFactory") 
    public SessionFactory sessionFactory(){ 
     return db2DBSessionfactory().getObject(); 
    } 

    @Bean 
    public LocalSessionFactoryBean db2DBSessionfactory() { 
     LocalSessionFactoryBean sessionFactoryBean = 
      new LocalSessionFactoryBean(); 
     sessionFactoryBean.setDataSource(db2DataSource()); 
     sessionFactoryBean.setPackagesToScan("com.edx"); 
     sessionFactoryBean. 
     setHibernateProperties(hibernateProperties()); 
     return sessionFactoryBean; 
    } 

    @Bean 
    public Properties hibernateProperties() { 
     Properties properties = new Properties(); 
     properties.put("hibernate.dialeCT... 
     properties.put("hibernate.show_sql", true); 
     properties.put("hibernate.connection.d 
     properties.put("hibernate.connection.url 
     properties.put("hibernate.connection.username", e 
     properties.put("hibernate.connection.passwor 
     return properties; 
    } 


    @Bean(destroyMethod="close") 
    public DataSource db2DataSource() { 
     try { 
      DriverManage.. 
      return dataSource; 
     } catch (Exception e) { 
      LOG.error("Unable to create connection pool",e); 
      return null; 
     } 

    } 



    @Bean 
    @Qualifier(value="db2TransactionManager") 
    public PlatformTransactionManager db2TransactionManager() { 
     HibernateTransactionManager htm=new 
     HibernateTransactionManager(db2DBSessionfactory().getObject()); 
     htm.setDataSource(db2DataSource()); 
     return htm; 
    } 

}

@Configuration 
@EnableTransactionManagement 
@ComponentScan("com.edx.oracle") 
@PropertySource(value={"classpath:...) 
public class ORAConfig { 
@Autowired 
private Environment env; 

    @Bean 
    public ProductDao productDao(){ 
     return new ProductService(); 
    } 


    @Bean 
    public SessionFactory oracleSessionFactory(){ 
     return oracleDBSessionfactory().getObject(); 
    } 

    @Bean 
    public LocalSessionFactoryBean oracleDBSessionfactory() { 
     LocalSessionFactoryBean sessionFactoryBean = 
      new LocalSessionFactoryBean(); 
     sessionFactoryBean.setDataSource(oracleDataSource()); 
     sessionFactoryBean.setPackagesToScan("com.edx.oracle"); 
     sessionFactoryBean.setHibernateProperties(hibernateProperties()); 
     return sessionFactoryBean; 
    } 


    @Bean 
    @Qualifier(value="oracleTransactionManager") 
    public PlatformTransactionManager oracleTransactionManager() { 
     HibernateTransactionManager htm=new 
     HibernateTransactionManager 
      (oracleDBSessionfactory().getObject()); 
     htm.setDataSource(oracleDataSource()); 
     return htm; 
    } 

    @Bean 
    public Properties hibernateProperties() { 
     Properties properties = new Properties(); 
     properties.put("hibernate.dialect" 
     ,env.getProperty("hibernate.dialect")); 
     properties.put("hibernate.show_sql", true); 
     properties.put("hibernate.connection.driver_class", 
     env.getProperty("jdbc.driverClassName")); 
     properties.put("hibernate.connection.url", 
     env.getProperty("jdbc.url")); 
     properties.put("hibernate.connection.username", 
     env.getProperty("jdbc.username")); 
     properties.put("hibernate.connection.password", 
     env.getProperty("jdbc.password")); 
     return properties; 
    } 



    @Bean 
    public DataSource oracleDataSource() { 
     try { 
      DriverManagerDataSource dm=new DriverManagerDataSource(); 
      dm.setDriverClassName(env.getProperty("jdbc.driverClassName")); 
      dm.setUsername(env.getProperty("jdbc.username")); 
      dm.setPassword(env.getProperty("jdbc.password")); 
      dm.setUrl(env.getProperty("jdbc.url")); 
      return dm; 
     } catch (Exception e) { 
      e.printStackTrace(); 
      LOG.error("Unable to create connection pool",e); 
      return null; 
     } 

    } 

}

@Repository 
    @Import(ORAConfig.class) 
    @Transactional("oracleTransactionManager") 
    public class UserService implements UserDao{ 

    @Autowired 
    private SessionFactory oracleSessionFactory; 
    private Logger LOG=LoggerFactory.getLogger(UserService.class); 
    private PayloadIndexExtractor payloadIndexExtractor; 
    public UserService() { 
    } 

    public UserService() { 
    } 


    public void save(final UserInfo user) { 
    try{ 
    //Changed from getCurrentSession()   
    Session session=oracleSessionFactory.openSession(); 
     session.save(user) ; 


    }catch(Exception e){ 
     e.printStackTrace(); 
     LOG.error("Failed to save user",e); 
    } 
} 

}

@Repository 
@Import(DB2Config.class) 
@Transactional("db2TransactionManager") 
public class ProductService implements ProductDao { 

public ProducrService() { 

} 
    @Autowired 
    private SessionFactory db2SessionFactory; 



    public void saveProduct(Product) { 
     sessionFactory.getCurrentSession().save(product); 
    } 

任意のアイデア?助けてください

+0

のようになります、あなたは@Qualifier'追加することができます

@Transactional

の両方がトランザクションを開始し、コミットされている他のHibernateTransactionManagersと意志の両方を含むことがあります(value = "oracleSessionFactory") 'を実行し、試行してください。 –

+0

私はこの問題を解決しませんでした – BreenDeen

答えて

0

あなたが必要とするものは、名前がtransactionManagerのBeanとしてChainedTransactionManagerです。世話をするよりも、それはコードが `ORAConfig`クラスで

@Bean(name = "transactionManager") 
public PlatformTransactionManager transactionManager(PlatformTransactionManager oracleTransactionManager, PlatformTransactionManager db2TransactionManager) 
     throws Exception { 
    return new ChainedTransactionManager(oracleTransactionManager, 
      db2TransactionManager); 
} 
+0

2トランザクションがインターリーブされています。その理由は、両方のトランザクションが全く無関係な2つの別々の非同期プロセスで同時に実行されているためです。したがって、save(Product)が実行中の場合、save(User)も実行され、save(Product)トランザクションに参加します。それらは2つの異なるデータベースであり、同じトランザクションマネージャが使用されているため、失敗します。 – BreenDeen

+0

答えは言及していませんでしたが、@ Transactionalアノテーションから値を削除する必要があります。トランザクションに参加して同時に開始するという概念はありません。 –

関連する問題