2017-06-07 24 views
1

私はHibernateとHikari DataSourceを持つSpringブートプロジェクトを持っています。私はセッションオブジェクトを取得するために注入されたSessionFactoryのオブジェクトを持ついくつかの機能を持っている場合は は、数日中に、私は(だけ解きにこの問題を再起動する)DB操作でassosiated任意のメソッドのような例外があります。JDBC接続を取得できません

org.springframework.transaction.CannotCreateTransactionException: 
Could not open JPA EntityManager for transaction; nested exception is 
javax.persistence.PersistenceException: 
org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection at 
...... 
Caused by: java.sql.SQLTransientConnectionException: HikariPool-1 - 
Connection is not available, request timed out after 30001ms. 

それはマニュアルに使用されるセッションに思えますこの問題を引き起こします。 (私は同じのconfigsと機能と同様のプロジェクトを持っていますが、SessionFactoryのとセッションを注入せずに...と私は全くこのような問題はありません)

application.yaml

spring: 
    jpa: 
    properties: 
     hibernate: 
     dialect : org.hibernate.dialect.PostgreSQLDialect 
     current_session_context_class: org.springframework.orm.hibernate5.SpringSessionContext 

をDataSourceConfig

@EnableJpaRepositories("com.my.project.config") 
@Configuration 
public class DataSourceConfig { 

    @Inject 
    private AppProperties properties; 

    @Bean(name = "dataSource") 
    public DataSource dataSource() { 
     AppProperties.DatabaseProperties dbProps = properties.getDatabaseProperties(); 
     HikariDataSource dataSource = new HikariDataSource(); 
     dataSource.setDriverClassName(org.postgresql.Driver.class.getName()); 
     dataSource.setJdbcUrl(
      dbProps.getProtocol().concat("://") 
       .concat(dbProps.getDbHost()).concat(":") 
       .concat(dbProps.getDbPort()).concat("/") 
       .concat(dbProps.getDbname()) 
     ); 
     dataSource.setUsername(dbProps.getUsername()); 
     dataSource.setPassword(dbProps.getPassword()); 
     dataSource.setMaximumPoolSize(30); 
     dataSource.setMinimumIdle(30); 

     return dataSource; 
    } 

    @Bean 
    public SessionFactory sessionFactory(HibernateEntityManagerFactory hemf) { 
     return hemf.getSessionFactory(); 
    } 
} 

LogRepositoryImpl

@Repository 
public class LogRepositoryImpl implements LogRepository { 

    @Autowired 
    private SessionFactory sessionFactory; 

    @Override 
    public List<Log> getLogs(int offset, int count) { 
     Criteria criteria = getSession().createCriteria(Log.class); 
     return criteria.setFirstResult(offset).setMaxResults(count).list(); 
    } 

    @Override 
    public void save(Log log) { 
     getSession().save(log); 
    } 

    private Session getSession() { 
     return sessionFactory.getCurrentSession(); 
    } 
} 

dataSource.setMaximumPoolSize(30)、 dataSource.setMinimumIdle();この問題は解決しませんでした

+0

最初の操作では機能しますが、選択/保存に成功した後にタイムアウトしますか? –

+0

はい、初めてアプリケーションを起動したときは、すべて正常です。 –

答えて

0

あなたのトランザクションの境界に問題があるように聞こえますが、プールへの接続を解放していません。あなたはLogRepositoryImplクラスに@Transactionalを入れてみませんか?

@Repository 
@Transactional 
public class LogRepositoryImpl implements LogRepository { 
    . . . 
} 
+0

私はLogRepositoryImplを直接使用しません。私はLogServiceとその実装に@Transactionalを注釈付きlogRepositoryと注釈付きで持っています –

+0

ああ、あなたの質問の情報に基づいてそれを知ることができませんでした。あなたは非常に並行した環境で走っていますか?一度に多くの接続が必要な場合は、プールサイズを増やすことができます。 –

+0

デフォルトでは、ヒッカリのデータソースはmaximumPoolSize = 10に設定されていますが、maximumPoolSizeを30に設定しても問題は解決しませんでした。 connectionPoolに空き接続がまったくないすぐに私はこの例外を取得すると、私は接続をすべて取得することはできません - この問題の解決を再開するだけです)。 私は5つのスケジュールされた方法とたくさんの残りのコントローラーを持っています。 –

関連する問題