2016-03-21 11 views
0

Ich habe 2 verschiedene Datenbanken. Ich konfiguriere jeden einzelnen und dann zugeordneten TransactionManager mit den jeweiligen @Transactional-Diensten. Das Problem ist, dass, wenn ich versuche, es zu speichern versucht, nur einen der Transaktionsmanager zu verwenden. Es ignoriert den anderen Transaktionsmanager vollständig. Hier sind die Konfigurationen: Bitte beachten Sie auch, dass diese 2 Speichervorgänge in zwei separaten asynchronen Springintegration-Prozessen fast gleichzeitig ablaufen, da die Anfrage über eine Empfängerliste an das Sichern (Produkt) und Speichern (Benutzer) gesendet wird. Könnte dies die Ursache des Problems sein?Spring verwendet dieselbe SessionFactory und ignoriert konfigurierte Transaktionsmanager

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

Irgendwelche Ideen, was mit meiner Konfiguration falsch ist? Bitte helfen Sie

+0

In der 'ORAConfig' Klasse aussehen soll, können Sie fügen Sie' @Qualifier (Wert = "oracleSessionFactory") 'über' oracleSessionFactory() 'Methode und versuchen. –

+0

Ich habe versucht, das Problem nicht zu lösen – BreenDeen

Antwort

0

Was Sie brauchen, ist ein ChainedTransactionManager als Bean mit dem Namen transactionManager. Es muss sowohl andere HibernateTransactionManagers und enthält als darauf achten, dass beide beginnen, und eine Transaktion mit @Transactional begehen

-Code wie

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

Die 2 Transaktionen werden interleaved. Der Grund ist, dass beide Transaktionen gleichzeitig in zwei separaten asynchronen Prozessen ausgeführt werden, die völlig unabhängig voneinander sind. Wenn save (Product) ausgeführt wird, wird also auch save (Benutzer) ausgeführt und die Transaktion zum Speichern (Product) hinzugefügt. Da es sich um zwei verschiedene Datenbanken handelt und der gleiche Transaktionsmanager verwendet wird, schlägt es fehl. – BreenDeen

+0

Ich habe es nicht die Antwort erwähnt, aber Sie müssen die Werte aus der @ Transactional Annotation entfernen. Es gibt kein Konzept, einer Transaktion beizutreten, sodass sie gleichzeitig gestartet werden. –

Verwandte Themen