स्प्रिंग बूट JPA - ऑटो पुन: कनेक्ट करना


107

मेरे पास एक छोटा सा स्प्रिंग बूट जेपीए वेब एप्लिकेशन है। यह अमेज़न बीनस्टॉक पर तैनात है और डेटा को बनाए रखने के लिए अमेज़न आरडीएस का उपयोग करता है। हालांकि इसका उपयोग अक्सर नहीं किया जाता है और इसलिए इस तरह के अपवाद के साथ थोड़ी देर बाद विफल हो जाता है:

com.mysql.jdbc.exception.jdbc4.CommunicationsException: सर्वर से सफलतापूर्वक प्राप्त अंतिम पैकेट 79,870,633 मिलीसेकंड पहले था।
सर्वर को सफलतापूर्वक भेजा गया अंतिम पैकेट 79,870,634 मिलीसेकंड पहले था। 'Wait_timeout' के सर्वर कॉन्फ़िगर किए गए मान से अधिक लंबा है। इस समस्या से बचने के लिए, क्लाइंट टाइमआउट के लिए सर्वर कॉन्फ़िगर किए गए मानों को बढ़ाते हुए, या कनेक्टर / J कनेक्शन प्रॉपर्टी 'autoReconnect = true' का उपयोग करके, आपको अपने आवेदन में उपयोग करने से पहले कनेक्शन की वैधता को समाप्त करने और / या परीक्षण करने पर विचार करना चाहिए।

मुझे यकीन नहीं है कि इस सेटिंग को कैसे कॉन्फ़िगर किया जाए और http://spring.io (हालांकि एक बहुत अच्छी साइट) पर इस पर जानकारी नहीं मिल सकती है । जानकारी के लिए कुछ विचार या संकेत क्या हैं?


अपने प्रिंट आउट DataSourceऔर इसके गुणों को सत्यापित करने के लिए इसका उपयोग करें । यदि आपके पास कोई परिभाषित है , तो stackoverflow.com/a/36586630/148844 स्प्रिंग बूट स्वतः कॉन्फ़िगर नहीं होगा । docs.spring.io/spring-boot/docs/1.5.16.RELEASE/reference/…DataSource@BeansDataSource
क्लो

जवाबों:


141

मुझे लगता है कि बूट आपके लिए कॉन्फ़िगर DataSourceकर रहा है। इस स्थिति में, और चूंकि आप MySQL का उपयोग कर रहे हैं, आप निम्न को अपने application.properties1.3 तक जोड़ सकते हैं

spring.datasource.testOnBorrow=true
spring.datasource.validationQuery=SELECT 1

Djxak टिप्पणी में बताया गया है, चार कनेक्शन पूल स्प्रिंग बूट का समर्थन करता है के लिए 1.4 + परिभाषित करता है विशिष्ट नामस्थान: tomcat, hikari, dbcp, dbcp2( dbcp1.5 की नहीं रहेगी)। आपको यह जांचने की आवश्यकता है कि आप किस कनेक्शन पूल का उपयोग कर रहे हैं और जांचें कि क्या यह सुविधा समर्थित है। ऊपर दिया गया उदाहरण टॉमकैट के लिए था इसलिए आपको इसे 1.4+ में निम्नानुसार लिखना होगा:

spring.datasource.tomcat.testOnBorrow=true 
spring.datasource.tomcat.validationQuery=SELECT 1

ध्यान दें कि के उपयोग autoReconnectकिया जाता है की सिफारिश नहीं की :

इस सुविधा के उपयोग की अनुशंसा नहीं की जाती है, क्योंकि इसमें सत्र स्थिति और डेटा संगतता से संबंधित दुष्प्रभाव होते हैं, जब अनुप्रयोग SQLException को ठीक से नहीं संभालते हैं, और इसका उपयोग केवल तब किया जाता है जब आप अपने आवेदन को कॉन्फ़िगर करने में असमर्थ होते हैं जिसके परिणामस्वरूप SQLException को संभालना संभव नहीं होता है मृत और बासी कनेक्शन ठीक से।


8
ऐसा इसलिए है क्योंकि हमने प्रलेखन में कुंजियाँ लिखने के तरीके से सामंजस्य बिठाया है। हमने हमेशा एक सुकून देने वाले बाइंडर का इस्तेमाल किया है spring.datasource.testOnBorrowऔर दोनों spring.datasource.test-on-borrowही ठीक काम करेंगे। अधिक विवरण के लिए दस्तावेज की जांच करें ।
स्टीफन निकोल

17
चूंकि यह दूसरों को भ्रमित कर सकता है: यह SELECT 1गारंटी देता है कि आवेदन से पहले इसे सौंप दिया गया है। उपयोग testOnBorrow = trueकरने से, पूल से उधार लेने से पहले वस्तुओं को मान्य किया जाएगा। यदि ऑब्जेक्ट मान्य करने में विफल रहता है, तो इसे पूल से हटा दिया जाएगा, और दूसरे को उधार लेने का प्रयास किया जाएगा। ध्यान दें - किसी भी प्रभाव के लिए एक सच्चे मूल्य के लिए, वैधीकरण® पैरामीटर को गैर-अशक्त स्ट्रिंग पर सेट किया जाना चाहिए।
रिक

14
चेतावनी! स्प्रिंग बूट में 1.4 + इस था बदल : चार कनेक्शन पूल वसंत का समर्थन करता है के लिए नए विशिष्ट नामस्थान वहाँ परिभाषित किया गया था: tomcat, hikari, dbcp, dbcp2। इसलिए, उदाहरण के लिए, tomcat-jdbcकनेक्शन-पूल के लिए, गुण होना चाहिए: spring.datasource.tomcat.testOnBorrow=trueऔर spring.datasource.tomcat.validationQuery=SELECT 1
रुस्लान Stelmachenko

1
यदि मैं स्वयं दो अलग-अलग डेटा स्रोत कॉन्फ़िगर कर रहा हूं तो मैं ये कॉन्फ़िगरेशन कैसे प्रदान करूं? क्या मुझे स्प्रिंगस्टैट. सोर्ससाइड.mydatasource1.tomcat.testOnBrief = true spring.datasource.mydatasource1.tomcat.validationQuery = SELECT 1 spring.datasource.mydatasource2.tomcat.testOnBreat = true springatatource = जैसे दोनों डेटा स्रोत के लिए यह कॉन्फ़िगरेशन प्रदान करने की आवश्यकता है। mydatasource2.tomcat.validationQuery = 1 का चयन करें या पालन करने के लिए कुछ और है ??
नीतीश कुमार

2
चेतावनी! यदि आप अपने ऐप में किसी भी DataSource @Bean को परिभाषित करते हैं, तो स्प्रिंग बूट पूल को कॉन्फ़िगर नहीं करेगाdocs.spring.io/spring-boot/docs/1.5.16.RELEASE/reference/… If you define your own DataSource bean, auto-configuration will not occur. मैंने OAuth2 के लिए एक गाइड का पालन किया था @Bean(name = "OAuth") public DataSource secondaryDataSource()...और यह ऑटो-कॉन्फ़िगर नहीं था और न ही उपयोग कर रहा था testOnBorrow
क्लो

28

उपरोक्त सुझाव मेरे काम नहीं आए। क्या वास्तव में काम किया आवेदन में निम्नलिखित लाइनों का समावेश था

spring.datasource.testWhileIdle = true
spring.datasource.timeBetweenEvictionRunsMillis = 3600000
spring.datasource.validationQuery = SELECT 1

आप स्पष्टीकरण यहाँ पा सकते हैं


5
आपके द्वारा जोड़ा गया लिंक कहता है कि यदि डेटाबेस कनेक्शन 8 घंटे से अधिक समय तक निष्क्रिय है, तो यह स्वचालित रूप से बंद हो जाता है और उपरोक्त त्रुटि हो जाएगी। तो, आपका समाधान लंबे समय तक अवधि के लिए कनेक्शन को निष्क्रिय नहीं रहने देना है। क्या ऐसा कोई तरीका है जिसे मैं पुनरारंभ होने के बाद SQL सर्वर से कनेक्ट कर सकता हूं?
अखेश्वर झा

9

Application.properties spring.datasource.tomcat.testOnBorrow=trueमें काम नहीं किया।

नीचे दिए गए प्रोग्राम की तरह बिना किसी समस्या के काम करना।

import org.apache.tomcat.jdbc.pool.DataSource;
import org.apache.tomcat.jdbc.pool.PoolProperties;    

@Bean
public DataSource dataSource() {
    PoolProperties poolProperties = new PoolProperties();
    poolProperties.setUrl(this.properties.getDatabase().getUrl());         
    poolProperties.setUsername(this.properties.getDatabase().getUsername());            
    poolProperties.setPassword(this.properties.getDatabase().getPassword());

    //here it is
    poolProperties.setTestOnBorrow(true);
    poolProperties.setValidationQuery("SELECT 1");

    return new DataSource(poolProperties);
}

1
यदि आप एक कस्टम डेटा स्रोत घोषित कर रहे हैं तो यह हो सकता है क्योंकि आप स्प्रिंग डिफ़ॉल्ट .tomcat का उपयोग करने का प्रयास कर रहे हैं। इसलिए यदि आप एक कस्टम डेटासोर्स बीन बनाते हैं, तो डेटा स्रोत बीन में @ConfigurationProperties (उपसर्ग = "spring.datasource.tomcat") जोड़ें और फिर इसे आपको एप्लिकेशन गुणों में सेट करने की अनुमति देनी चाहिए। मेरा उदाहरण .. @ बीन (नाम = "managementDataSource") @ConfigurationProperties (उपसर्ग = "प्रबंधन.datasource") सार्वजनिक डेटा स्रोत डेटा स्रोत () ({DataSourceBuilder.cloe) लौटें (); } management.datasource.test-on-credit = true
जस्टिन

8

मैं बस स्प्रिंग बूट 1.4 में चला गया और पाया कि इन गुणों का नाम बदल दिया गया था:

spring.datasource.dbcp.test-while-idle=true
spring.datasource.dbcp.time-between-eviction-runs-millis=3600000
spring.datasource.dbcp.validation-query=SELECT 1

2
नाम समतुल हैं। स्प्रिंग बूट डॉक्स में संपत्ति के नामकरण पर अनुभाग देखें ।
स्टीफन हैरिसन

@StephenHarrison: dbcp पर ध्यान दें। * उपसर्ग 1.4 में जोड़ा गया, इस मामले में आराम बंधन लागू नहीं होता है।
YM

1
@Pawel: आपकी परियोजना में पूलिंग कार्यान्वयन किस आधार पर उपलब्ध है, यह dbcp नहीं हो सकता है। * आपके लिए गुण, SQL के साथ स्प्रिंग बूट देखें और संबंधित डेटा स्रोत
YM

4

whoami का उत्तर सही है। सुझाए गए गुणों का उपयोग करते हुए मैं इसे काम करने में असमर्थ था (स्प्रिंग बूट 1.5.3 का उपयोग करके। कृपया)

मैं अपना उत्तर जोड़ रहा हूँ क्योंकि यह एक पूर्ण विन्यास वर्ग है, इसलिए यह किसी को स्प्रिंग बूट का उपयोग करने में मदद कर सकता है:

@Configuration
@Log4j
public class SwatDataBaseConfig {

    @Value("${swat.decrypt.location}")
    private String fileLocation;

    @Value("${swat.datasource.url}")
    private String dbURL;

    @Value("${swat.datasource.driver-class-name}")
    private String driverName;

    @Value("${swat.datasource.username}")
    private String userName;

    @Value("${swat.datasource.password}")
    private String hashedPassword;

    @Bean
    public DataSource primaryDataSource() {
        PoolProperties poolProperties = new PoolProperties();
        poolProperties.setUrl(dbURL);
        poolProperties.setUsername(userName);
        poolProperties.setPassword(password);
        poolProperties.setDriverClassName(driverName);
        poolProperties.setTestOnBorrow(true);
        poolProperties.setValidationQuery("SELECT 1");
        poolProperties.setValidationInterval(0);
        DataSource ds = new org.apache.tomcat.jdbc.pool.DataSource(poolProperties);
        return ds;
    }
}

क्या आपको पता है कि इस कस्टम कोड की आवश्यकता क्यों है और क्यों स्प्रिंग इन संपत्तियों को सिर्फ गुण फ़ाइल से नहीं पढ़ेगा? मेरी फ़ाइल में कई डेटा स्रोत हैं और यह बिना किसी समस्या के बाकी सभी को पढ़ता है।
अंकल लंबे बाल

3

मुझे भी ऐसी ही समस्या है। स्प्रिंग 4 और टॉमकैट 8. मैं स्प्रिंग कॉन्फ़िगरेशन के साथ समस्या का समाधान करता हूं

<bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
    <property name="initialSize" value="10" />
    <property name="maxActive" value="25" />
    <property name="maxIdle" value="20" />
    <property name="minIdle" value="10" />
     ...
    <property name="testOnBorrow" value="true" />
    <property name="validationQuery" value="SELECT 1" />
 </bean>

मैंने परीक्षण किया है। यह अच्छा काम करता है! डेटाबेस को फिर से जोड़ने के लिए यह दो लाइन सब कुछ करती है:

<property name="testOnBorrow" value="true" />
<property name="validationQuery" value="SELECT 1" />

3

मामले में कोई भी कस्टम डेटा स्रोत का उपयोग कर रहा है

@Bean(name = "managementDataSource")
@ConfigurationProperties(prefix = "management.datasource")
public DataSource dataSource() {
    return DataSourceBuilder.create().build();
}

गुण निम्नलिखित की तरह दिखना चाहिए। उपसर्ग के साथ @ConfigurationProperties को देखें। उपसर्ग वास्तविक संपत्ति के नाम से पहले सब कुछ है

management.datasource.test-on-borrow=true
management.datasource.validation-query=SELECT 1

स्प्रिंग संस्करण 1.4.4 के लिए एक संदर्भ


2

जैसा कि कुछ लोग पहले से ही बताते हैं, वसंत-बूट 1.4+ में चार कनेक्शन पूल के लिए विशिष्ट नामस्थान हैं। डिफ़ॉल्ट रूप से, hikaricp का उपयोग स्प्रिंग-बूट 2+ में किया जाता है। इसलिए आपको यहां एसक्यूएल निर्दिष्ट करना होगा। डिफ़ॉल्ट है SELECT 1। यहाँ उदाहरण के लिए आपको DB2 के लिए क्या चाहिए होगा: spring.datasource.hikari.connection-test-query=SELECT current date FROM sysibm.sysdummy1

चेतावनी : अपने ड्राइवर JDBC4 का समर्थन करता है, तो हम सशक्त इस संपत्ति की स्थापना नहीं की सलाह देते हैं। यह "विरासत" ड्राइवरों के लिए है जो JDBC4 Connection.isValid () API का समर्थन नहीं करते हैं। यह वह क्वेरी है जिसे एक कनेक्शन से ठीक पहले निष्पादित किया जाएगा ताकि आप पूल से यह प्रमाणित कर सकें कि डेटाबेस से कनेक्शन अभी भी जीवित है। फिर, इस संपत्ति के बिना पूल चलाने की कोशिश करें, अगर आपका ड्राइवर आपको बताने के लिए JDBC4 अनुरूप नहीं है तो HikariCP एक त्रुटि दर्ज करेगा। डिफ़ॉल्ट: कोई नहीं


0

जो लोग इसे कई डेटा स्रोतों के साथ YAML से करना चाहते हैं, उनके बारे में एक महान ब्लॉग पोस्ट है: https://springframework.guru/how-to-configure-multiple-data-sources-in-a-spring-boot -आवेदन /

यह मूल रूप से कहता है कि आप दोनों को डेटा स्रोत गुण और डेटा स्रोत इस तरह कॉन्फ़िगर करने की आवश्यकता है:

@Bean
@Primary
@ConfigurationProperties("app.datasource.member")
public DataSourceProperties memberDataSourceProperties() {
    return new DataSourceProperties();
}

@Bean
@Primary
@ConfigurationProperties("app.datasource.member.hikari")
public DataSource memberDataSource() {
    return memberDataSourceProperties().initializeDataSourceBuilder()
            .type(HikariDataSource.class).build();
}

@Primaryअन्य डेटा स्रोत से निकालना न भूलें ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.