5

ho bisogno di impostare alcune proprietà specifiche di connessione JDBC Oracle, al fine di accelerare il lotto INSERT s (defaultBatchValue) e massa SELECT s (defaultRowPrefetch) . ho avuto suggestions come raggiungere questo obiettivo con DBCP (Grazie a M. Deinum), ma mi piacerebbe:come impostare le proprietà di connessione personalizzata su DataSource in primavera Boot 1.3.x con piscina di default il collegamento Tomcat

  • mantenere il Tomcat pool di connessioni JDBC predefinita
  • mantenere application.yml per la configurazione

Stavo pensando a una richiesta di funzionalità per supportare spring.datasource.custom_connection_properties o simili in futuro e per questo ho cercato di fingere che fosse già possibile. Ho fatto questo passando le informazioni utili durante la creazione del DataSource e manipolato la creazione del DataSource in questo modo:

@Bean 
public DataSource dataSource() { 
    DataSource ds = null; 

    try { 
     Field props = DataSourceBuilder.class.getDeclaredField("properties"); 
     props.setAccessible(true); 
     DataSourceBuilder builder = DataSourceBuilder.create(); 
     Map<String, String> properties = (Map<String, String>) props.get(builder); 

     properties.put("defaultRowPrefetch", "1000"); 
     properties.put("defaultBatchValue", "1000"); 

     ds = builder.url("jdbc:oracle:thin:@xyz:1521:abc").username("ihave").password("wonttell").build(); 

     properties = (Map<String, String>) props.get(builder); 

     log.debug("properties after: {}", properties); 
    } ... leaving out the catches ... 
    } 
    log.debug("We are using this datasource: {}", ds); 
    return ds; 
} 

Nei registri posso vedere che sto creando la corretta DataSource:

2016-01-18 14:40:32.924 DEBUG 31204 --- [   main] d.a.e.a.c.config.DatabaseConfiguration : We are using this datasource: [email protected]{ConnectionPool[defaultAutoCommit=null; ... 

2016-01-18 14:40:32.919 DEBUG 31204 --- [   main] d.a.e.a.c.config.DatabaseConfiguration : properties after: {password=wonttell, driverClassName=oracle.jdbc.OracleDriver, defaultRowPrefetch=1000, defaultBatchValue=1000, url=jdbc:oracle:thin:@xyz:1521:abc, username=ihave} 

l'attuatore mi dimostra che il mio codice sostituito l'origine dati:

enter image description here

Ma le impostazioni non sono un ctivato, che posso vedere durante la profilazione dell'applicazione. Il defaultRowPrefetch è ancora a 10 che causa il mio SELECT s di essere molto più lento di quanto sarebbe se 1000 è stato attivato.

+0

modifica delle proprietà è non andare a lavorare, quelle non sono le proprietà che si desidera modificare ... –

+0

@ M.Deinum ho pensato queste erano le proprietà passarono durante la connessione al driver JDBC. Cosa li rende diversi da quello che pensavo? – Marged

+0

No non vengono passati durante la connessione. Queste sono le proprietà interne utilizzate da 'DataSourceBuilder' e contengono solo un piccolo numero di proprietà utilizzabili per uso interno. –

risposta

7

L'impostazione delle piscine connectionProperties dovrebbe funzionare. Questi saranno passati al driver JDBC. Aggiungi questo a application.properties:

spring.datasource.connectionProperties: defaultRowPrefetch=1000;defaultBatchValue=1000 

Edit (alcune informazioni di base):

noti inoltre che è possibile configurare qualsiasi dell'attuazione DataSource proprietà specifiche tramite spring.datasource *:. Fare riferimento a la documentazione dell'implementazione del pool di connessioni utilizzata per maggiori dettagli.

fonte: spring-boot documentation

+0

Questo sembra funzionare per le proprietà che vengono passate nell'URL jdbc. Nel mio scenario 'defaultRowPrefetch' deve essere passato in un insieme di' Properties' che è il secondo parametro usato in 'getConnection (String url, Proprietà prop)' e segue subito dopo l'url jdbc. Ma comunque grazie per la tua modifica. – Marged

+3

Come accennato [qui] (http://stackoverflow.com/a/40255073/993417) dallo sviluppatore principale su Spring Boot, a partire dalla versione 1.4, tale proprietà non esiste più. –

0

Alcune informazioni aggiuntive per completare la risposta @Cyril. Se vuoi usare la sua risposta, non la mia.

Ero un po 'perplesso di quanto sia facile impostare proprietà di connessione aggiuntive che alla fine vengono utilizzate durante la creazione della connessione al database. Quindi ho fatto un po 'di ricerca.

spring.datasource.connectionProperties è non menzionati nella reference. Ho creato un issue per questo motivo. Se avessi usato il Spring Boot YML editor, avrei visto quali proprietà sono supportate.Ecco cosa STS suggerisce quando si crea un application.yml e colpire Ctrl + Spazio:

Autocomplete for spring.datasource

Il trattino non importa, perché di relaxed binding, ma se si interpreta letteralmente il nome propertys è spring.datasource.connection-properties.

la correttezza di installazione in application.yml si presenta così:

spring: 
    datasource: 
     connection-properties: defaultBatchValue=1000;defaultRowPrefetch=1000 
     ... 

Questo viene onorata che è dimostrato dai miei misurazioni perf4j di massa SELECT s.

Prima:

2016-01-19 08: 58: 32,604 INFO 15108 --- [principale] org.perf4j.TimingLogger: ora di inizio tag [1.453.190,311227 millions] [1377] [ottenere elementi ]

Dopo:

2016-01-19 08: 09: 18,214 INFO 9152 --- [principale] org.perf4j.TimingLogger: start [1.453.187,358066 millions] tempo [147] tag [ottenere elementi]

Il tempo necessario per completare l'istruzione SQL scende da 1377ms a 147, che è un guadagno enorme in termini di prestazioni.

+0

Non è menzionato perché non è una proprietà disponibile generale. Funziona perché si utilizza Tomcat JDBC, se si utilizzasse per esempio Commons DBCP o un pool basato su HikariCP, la proprietà non sarebbe disponibile né funzionante. È dovuto al legame che funziona (forse questa è una caratteristica che dovrebbe essere documentata). –

+0

Sei corretto, per gli altri pool di connessione abbiamo bisogno di un approccio che hai mostrato in [la mia altra domanda] (http://stackoverflow.com/questions/34789220/optimizing-jdbc-fetch-size-by-use-of-spring -properties -boots applicazione). Ma siccome il pool JDBC di Tomcat è l'impostazione predefinita, non farebbe male menzionare specifiche opzioni di configurazione ;-) Ho creato un problema a Github per questo motivo. – Marged

+0

Come ho provato a chiarire non c'è un default ... Dipende dalle dipendenze che hai. –

1

Dopo aver scavato per un po 'nel codice Tomcat, ho scoperto che lo dataSource.getPoolProperties().getDbProperties() è l'oggetto Properties che verrà effettivamente utilizzato per generare connessioni per il pool.

Se si utilizza l'approccio BeanPostProcessor citato da @ m-Deinum, ma invece utilizza per popolare la dbProperties in questo modo, si dovrebbe essere in grado di aggiungere le proprietà in un modo che li rende bastone e viene passato al driver Oracle .

import java.util.Properties; 
import org.apache.tomcat.jdbc.pool.DataSource; 
import org.apache.tomcat.jdbc.pool.PoolConfiguration; 

@Component 
public class OracleConfigurer implements BeanPostProcessor { 
    @Override 
    public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException { 
     if (bean instanceof DataSource) { 
      DataSource dataSource = (DataSource)bean; 
      PoolConfiguration configuration = dataSource.getPoolProperties(); 
      Properties properties = configuration.getDbProperties(); 
      if (null == properties) properties = new Properties(); 
      properties.put("defaultRowPrefetch", 1000); 
      properties.put("defaultBatchValue", 1000); 
      configuration.setDbProperties(properties); 
     } 
     return bean; 
    } 

    @Override 
    public Object postProcessAfterInitialization(Object bean, String name) throws BeansException { 
     return bean; 
    } 
}