2017-02-11 3 views
0

挨拶で休止+春の使い方:エクアドルから3人のトランザクションデータベース

現在、私は私が3つの異なるデータベース上で操作を実行する必要があるプロジェクトを作成しました。この目的のために、私はHibernate ORM 5.2.7、Spring Framework 4.3.6および他のライブラリとの接続プールの実装のための他のライブラリを使用することに決めました。

@Repository 
public class BitacoraFacturasDetalleDao extends GenericDaoImpl<BitacoraFacturasDetalle, Integer>{ 

private final static Logger LOGGER = Logger.getLogger(BitacoraFacturasDetalleDao.class); 

@Qualifier("sessionFactoryBitacora") 
@Autowired 
private SessionFactory sessionFactory; 

public BitacoraFacturasDetalleDao() { 
    super(BitacoraFacturasDetalle.class); 
} 

public BitacoraFacturasDetalle findByEstablecimientoAndPuntoEmisionAndSecuencial(String establecimiento, String puntoEmision, String secuencial) { 
    LOGGER.info("evento findByEstablecimientoAndPuntoEmisionAndSecuencial"); 
    BitacoraFacturasDetalle ret = (BitacoraFacturasDetalle) getCurrentSession().createNamedQuery("BitacoraFacturasDetalle.findByEstablecimientoAndPuntoEmisionAndSecuencial").setParameter("establecimiento", establecimiento).setParameter("puntoEmision", puntoEmision).setParameter("secuencial", secuencial).uniqueResult(); 
    return ret; 
} 

    @Override 
    protected Session getCurrentSession() { 
     return this.sessionFactory.getCurrentSession(); 
    } 

} 

トランザクションオブジェクトは、次のとおりです。

@Configuration 
@ComponentScan("fttg.*") 
@EnableTransactionManagement 
@EnableScheduling 
@PropertySources({ 
     @PropertySource("classpath:application.properties"), 
     @PropertySource("classpath:schedule.properties") 
}) 
public class ApplicationConfig { 

     @Autowired 
     private Environment environment; 

@Bean(destroyMethod = "close") 
public BasicDataSource dataSourceBitacora() { 
    BasicDataSource dataSource = new BasicDataSource(); 
    dataSource.setDriverClassName(environment.getRequiredProperty("postgres.jdbc.driver")); 
    dataSource.setUrl(environment.getRequiredProperty("bitacora.jdbc.url")); 
    dataSource.setUsername(environment.getRequiredProperty("bitacora.jdbc.username")); 
    dataSource.setPassword(environment.getRequiredProperty("bitacora.jdbc.password")); 
    dataSource.setPoolPreparedStatements(true); 
    dataSource.setInitialSize(4); 
    dataSource.setMaxTotal(4); 
    dataSource.setMaxIdle(2); 
    dataSource.setMinIdle(1); 
    dataSource.setDefaultAutoCommit(Boolean.FALSE); 
    return dataSource; 
} 

@Bean(destroyMethod = "close") 
public BasicDataSource dataSourceFacturacion() { 
    BasicDataSource dataSource = new BasicDataSource(); 
    dataSource.setDriverClassName(environment.getRequiredProperty("postgres.jdbc.driver")); 
    dataSource.setUrl(environment.getRequiredProperty("facturacion.jdbc.url")); 
    dataSource.setUsername(environment.getRequiredProperty("facturacion.jdbc.username")); 
    dataSource.setPassword(environment.getRequiredProperty("facturacion.jdbc.password")); 
    dataSource.setPoolPreparedStatements(true); 
    dataSource.setInitialSize(1); 
    dataSource.setMaxTotal(4); 
    dataSource.setDefaultAutoCommit(Boolean.FALSE); 
    return dataSource; 
} 

@Bean(destroyMethod = "close") 
public BasicDataSource dataSourceSietab() { 
    BasicDataSource dataSource = new BasicDataSource(); 
    dataSource.setDriverClassName(environment.getRequiredProperty("postgres.jdbc.driver")); 
    dataSource.setUrl(environment.getRequiredProperty("sietab.jdbc.url")); 
    dataSource.setUsername(environment.getRequiredProperty("sietab.jdbc.username")); 
    dataSource.setPassword(environment.getRequiredProperty("sietab.jdbc.password")); 
    dataSource.setPoolPreparedStatements(true); 
    dataSource.setInitialSize(1); 
    dataSource.setMaxTotal(2); 
    dataSource.setDefaultAutoCommit(Boolean.FALSE); 
    return dataSource; 
} 

@Bean 
public LocalSessionFactoryBean sessionFactoryBitacora() { 
    LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); 
    sessionFactory.setDataSource(dataSourceBitacora()); 
    sessionFactory.setPackagesToScan(environment.getRequiredProperty("bitacora.sessionFactory.packagesToScan")); 
    Properties properties = new Properties(); 
    properties.put("hibernate.dialect", environment.getRequiredProperty("postgres.hibernate.dialect")); 
    properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql")); 
    sessionFactory.setHibernateProperties(properties); 
    return sessionFactory; 
} 

@Bean 
public LocalSessionFactoryBean sessionFactoryFacturacion() { 
    LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); 
    sessionFactory.setDataSource(dataSourceFacturacion()); 
    sessionFactory.setPackagesToScan(environment.getRequiredProperty("facturacion.sessionFactory.packagesToScan")); 
    Properties properties = new Properties(); 
    properties.put("hibernate.dialect", environment.getRequiredProperty("postgres.hibernate.dialect")); 
    properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql")); 
    sessionFactory.setHibernateProperties(properties); 
    return sessionFactory; 
} 

@Bean 
public LocalSessionFactoryBean sessionFactorySietab() { 
    LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); 
    sessionFactory.setDataSource(dataSourceSietab()); 
    sessionFactory.setPackagesToScan(environment.getRequiredProperty("sietab.sessionFactory.packagesToScan")); 
    Properties properties = new Properties(); 
    properties.put("hibernate.dialect", environment.getRequiredProperty("postgres.hibernate.dialect")); 
    properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql")); 
    sessionFactory.setHibernateProperties(properties); 
    return sessionFactory; 
} 

@Bean 
public HibernateTransactionManager transactionManagerBitacora() { 
    HibernateTransactionManager txManager = new HibernateTransactionManager(); 
    txManager.setSessionFactory(sessionFactoryBitacora().getObject()); 
    return txManager; 
} 

@Bean 
public HibernateTransactionManager transactionManagerFacturacion() { 
    HibernateTransactionManager txManager = new HibernateTransactionManager(); 
    txManager.setSessionFactory(sessionFactoryFacturacion().getObject()); 
    return txManager; 
} 

@Bean 
public HibernateTransactionManager transactionManagerSietab() { 
    HibernateTransactionManager txManager = new HibernateTransactionManager(); 
    txManager.setSessionFactory(sessionFactorySietab().getObject()); 
    return txManager; 
} 
} 

DAOS構成は、データベース内のすべてのオブジェクトでも同じです:春のコンテキストのコンフィギュレーションの実現のために、私は以下を示し注釈で私をサポート次のように実装:

@Service("facturasService") 
@Transactional(value="transactionManagerFacturacion", readOnly = false) 
public class FacturasServiceImpl implements FacturasService, Serializable { 

private static final long serialVersionUID = 1L; 
private final static Logger LOGGER =  Logger.getLogger(FacturasServiceImpl.class); 

@Autowired 
private FacturasCabeceraDao facturasCabeceraDao; 

@Override 
public boolean save(FacturasCabecera factura) { 
    LOGGER.info("evento save"); 
    return facturasCabeceraDao.save(factura); 
} 

} 

@Service("bitacoraFacturasDetalleService") 
@Transactional(readOnly = false, value = "transactionManagerBitacora") 
public class BitacoraFacturasDetalleServiceImpl implements BitacoraFacturasDetalleService, Serializable { 

private static final long serialVersionUID = 1L; 
private final static Logger LOGGER = Logger.getLogger(BitacoraFacturasDetalleServiceImpl.class); 

@Autowired 
private BitacoraFacturasDetalleDao bitacoraFacturasDetalleDao; 

@Override 
public boolean save(BitacoraFacturasDetalle b) { 
    LOGGER.info("evento save"); 
    return bitacoraFacturasDetalleDao.save(b); 
} 

@Override 
public boolean edit(BitacoraFacturasDetalle b) { 
    LOGGER.info("evento edit"); 
    return bitacoraFacturasDetalleDao.edit(b); 
} 

@Override 
@Transactional(readOnly = true, value = "transactionManagerBitacora") 
public BitacoraFacturasDetalle findByEstablecimientoAndPuntoEmisionAndSecuencial(String establecimiento, String puntoEmision, String secuencial) { 
    LOGGER.info("evento findByEstablecimientoAndPuntoEmisionAndSecuencial"); 
    return bitacoraFacturasDetalleDao.findByEstablecimientoAndPuntoEmisionAndSecuencial(establecimiento, puntoEmision, secuencial); 
} 

} 

、石英、私はそこを通ってサービスの3つの異なる種類を呼び出す実装するサービスで: データベースから情報を取得し、いくつかのxmlを生成し、2番目のデータベースにbitacoraのレコードを挿入します。このアクションが正しい場合は、最初のベースから取得したレコードの状態を更新してから、生成されたxmlsそして、このアクションが正しく実行された場合、私は2番目のデータベースのレコードに状態を変更し、2番目のテーブルに3番目のデータベースのマスターと詳細を入力します。

次に、私が呼び出しを行うコード:

@Service 
public class ScheduleService implements Serializable { 
     @Autowired 
     private LocalidadService localidadService; 
     @Autowired 
     private CooperativaService cooperativaService; 
     @Autowired 
     private BoletoTasaService boletoTasaService; 
     @Autowired 
     private BitacoraFacturasDetalleService bitacoraFacturasDetalleService; 
     @Autowired 
     private InformacionTributariaService informacionTributariaService; 
     @Autowired 
     private ClientesService clientesService; 
     @Autowired 
     private FacturasService facturasService; 

     @Scheduled(cron = "${schedule.cronExpresion}") 
     public void start() { 
      if(XMLUtil.generarXML(factura, XML_GENERADO)) { 
      LOGGER.info("XML para la factura " + SECUENCIAL_DOCUMENTO + " generado correctamente"); 
      //code that fills a javaBean 
      //Execution of service that inserts in the database # 2 
      if(bitacoraFacturasDetalleService.save(bitacoraFacturaDetalle)) { 
           LOGGER.info("Factura " + SECUENCIAL_DOCUMENTO + " registrada en bitacora correctamente"); 
       // object retrieved from database # 1 to be changed status not to be taken into account in future 
       tasa.setStatusFacturacionElectronica("P"); 
       if(boletoTasaService.update(tasa)) { 
       //Other post-upgrade operations 

      } 
     } 
    } 
} 

このコードは、次回のdiffの挿入または更新の処理後に、一定量のレジスタ(データベース1の約700または800)まで機能します多くの時間のためにコードが「スリープ」に戻る

本番環境に移行する前に実行されたテストでは、このシナリオでは3つのデータベースのコピーを作成します。それらと相互作用するシステムおよび/またはインターフェースのうちの少なくとも1つを含む。

"問題"の原因は、プログラミング・コード、トランザクション・オブジェクトを定義する戦略(私はJTAを使用するように読んでお勧めしましたが、トランザクションスレッド(データベース上の操作を制御するサービス))、またはこの不都合が他のアプリケーションの集計によって異なるデータベースのテーブルに提示された場合

スプリング構成に問題がある場合は、トランザクションサービスの定義、またはこの目的のためにJTAを使用する必要がある場合

以前に私が情報を抽出する1つまたは複数のデータベースと、挿入を行うデータベースのみを使用していたこのスキームを使用したことを示すことができます。一方、特定の状況では3つのデータベースに書かれています

答えて

0

問題については、何が間違っているのかを正確に伝えるのは難しいです。それにもかかわらず、私はあなたにいくつかのヒントを与えることができます:

  1. 接続プーリングをまったく使用していません。 BasicDataSourceをHikariCP接続プールに置き換えてください。
  2. 長時間実行されるトランザクションの代わりに。それを分割してみてください。 Spring Integrationを使用してパイプラインを構築してください。各データベーストランザクションは、一度に小さなデータサブセットのみを処理する必要があります。このようにして、VACUUMは実行時間の長いトランザクションを使用している場合よりも実行する機会が増えます。
+0

私は、3番目のデータベースには2番目の休止状態用と1番目のjdbc用だけを使用していると考えていました。どう思いますか? –

+0

私はそれを行う際にポイントが表示されません。 DBが詰まっている理由を調べてみてください。それはロックを待つ必要がありますか、またはVACUUMプロセスかもしれません。 –

関連する問題