Sto utilizzando Spring MVC per creare un sottile strato su un database SQL Server. Quando ho iniziato a testare, sembra che non gestisca lo stress molto bene :). Sto usando Apache Commons DBCP per gestire il pool di connessioni e l'origine dati.Qual è il modo corretto per gestire le connessioni JDBC con Spring e DBCP?
Quando ho tentato per la prima volta ~ 10-15 connessioni simultanee, si bloccava e dovevo riavviare il server (per Dev sto usando Tomcat, ma dovrò essere distribuito su Weblogic alla fine).
Queste sono le mie definizioni bean Spring:
<bean id="dataSource" destroy-method="close"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
<property name="url" value="[...]"/>
<property name="username" value="[...]" />
<property name="password" value="[...]" />
</bean>
<bean id="partnerDAO" class="com.hp.gpl.JdbcPartnerDAO">
<constructor-arg ref="dataSource"/>
</bean>
<!-- + other beans -->
e questo è come li uso:
// in the DAO
public JdbcPartnerDAO(DataSource dataSource) {
jdbcTemplate = new JdbcTemplate(dataSource);
}
// in the controller
@Autowired
private PartnerDAO partnerDAO;
// in the controller method
Collection<Partner> partners = partnerDAO.getPartners(...);
Dopo aver letto in giro un po ', ho trovato le proprietà maxWait
, maxActive
e maxIdle
per il BasicDataSource (da GenericObjectPool). Ecco il problema Non sono sicuro di come dovrei impostarli, in termini di prestazioni. Da quello che so, Spring dovrebbe gestire le mie connessioni quindi non dovrei preoccuparmi di rilasciarle.
<bean id="dataSource" destroy-method="close"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
<property name="url" value="[...]"/>
<property name="username" value="[...]" />
<property name="password" value="[...]" />
<property name="maxWait" value="30" />
<property name="maxIdle" value="-1" />
<property name="maxActive" value="-1" />
</bean>
In primo luogo, ho impostato maxWait
, in modo che non sarebbe appendere e invece un'eccezione quando nessun collegamento era disponibile dalla piscina. Il messaggio di eccezione era:
Impossibile ottenere la connessione JDBC; l'eccezione annidata è org.apache.commons.dbcp.SQLNestedException: Impossibile ottenere una connessione, errore di piscina Timeout in attesa di oggetto inattivo
Ci sono alcune query a lungo in esecuzione, ma l'eccezione è stato gettato, indipendentemente dalla complessità query.
Quindi, ho impostato maxActive e maxIdle in modo che non generasse le eccezioni in primo luogo. I valori predefiniti sono 8 per maxActive
e maxIdle
(non capisco perché); se li metto a -1 non ci sono più eccezioni generate e tutto sembra funzionare.
Considerando che questa applicazione deve supportare un numero elevato di richieste simultanee, è ok lasciare le impostazioni su infinito? Spring gestirà davvero le mie connessioni, considerando gli errori che stavo ricevendo? Devo passare a C3P0 considerando che è un po 'morto?
Se si ottengono eccezioni, la registrazione dello stacktrace consente di identificare facilmente il problema. Esistono query a lungo termine in cui vengono visualizzati i problemi? –
Ho aggiornato il mio post con il messaggio di eccezione e alcune informazioni extra. –