【问题标题】:How to close the connection in Spring Boot after jdbcTemplate executes the query?jdbcTemplate执行查询后如何关闭Spring Boot中的连接?
【发布时间】:2017-04-16 05:51:46
【问题描述】:

在 Spring Boot 中,jdbcTemplate 在执行查询后不会自动关闭连接吗? 在这种情况下,我正在使用 jdbcTemplate(它连接到 teradata)执行查询,但在执行查询后会话没有关闭。如何关闭会话?

这是我的 dao 文件 -

@Component
public class DDLReviewDao { 

    @Autowired
    @Qualifier("devbJdbc")
    private JdbcTemplate jdbcTemplate;

    public static final Logger logger = LogManager.getLogger(DDLReviewDao.class);

    public List<DDLObject> getDDLReviewData(DDLQuery ddlQuery) {

        String selectSql = MacroGenerator.generateMacro(ddlQuery);                  
        List<DDLObject> ddlObject = jdbcTemplate.query(selectSql, new DDLMapper());                 
        logger.info(ddlObject);
        return ddlObject;
    }

}

【问题讨论】:

  • 如果您使用的是 maven,请分享 pom.xml。

标签: java spring jdbc spring-boot jdbctemplate


【解决方案1】:

根据 spring boot 文档,您可以像这样为 spring 池分配最大连接数:

spring.datasource.tomcat.max-active=50

这显然只适用于嵌入式网络服务器。如果要将它部署到 Jboss 之类的东西上,则必须在服务器配置文件中配置该属性。

【讨论】:

    【解决方案2】:

    在 Spring Boot 中,jdbcTemplate 是否不会关闭连接 执行查询后自动一次?

    应该关闭连接还是返回连接池(以防DataSource被池化)?

    如果您阅读http://grepcode.com/file/repo1.maven.org/maven2/org.springframework/spring-jdbc/4.1.7.RELEASE/org/springframework/jdbc/core/JdbcTemplate.java#JdbcTemplate.execute%28org.springframework.jdbc.core.StatementCallback%29的源代码,可以归结为:

    public static void doReleaseConnection(Connection con, DataSource dataSource) throws SQLException {
        if (con == null) {
            return;
        }
        if (dataSource != null) {
            ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
            if (conHolder != null && connectionEquals(conHolder, con)) {
                // It's the transactional Connection: Don't close it.
                conHolder.released();
                return;
            }
        }
        logger.debug("Returning JDBC Connection to DataSource");
        doCloseConnection(con, dataSource);
    }
    

    public static void doCloseConnection(Connection con, DataSource dataSource) throws SQLException {
        if (!(dataSource instanceof SmartDataSource) || ((SmartDataSource) dataSource).shouldClose(con)) {
            con.close();
        }
    }
    

    最有可能的是,如果 DataSource 实例是池化的,则连接会被释放以供重用,而不是关闭。

    【讨论】:

      【解决方案3】:

      JdbcTemplatejavax.sql.DataSource 实现中获取连接 - 传递给它的构造函数link

      DataSources 可以是 basic(为每个请求创建 Connection 对象)或 pooling(具有连接池并且只是“借用”一个给定的请求的使用)。

      因此,连接似乎没有关闭,因为您已将一些池数据源传递给名为 devbJdbcJdbcTemplate。如果你真的想关闭每个打开的连接来执行JdbcTemplate 工作,你可以使用基本的DataSource 实现:org.springframework.jdbc.datasource.SimpleDriverDataSource,就像这样:

      @Configuration
      class DevbConfig {
      
          @Bean(name = "devbDataSource")
          DataSource devbDataSource() {
              try {
                  return new SimpleDriverDataSource(DriverManager.getDriver("jdbc:..."), "jdbc:...", "username", "password");
              } catch (SQLException e) {
                  throw new RuntimeException(e);
              }
          }
      
          @Bean(name = "devbJdbc")
          JdbcTemplate devbJdbc(@Qualifier("devbDataSource") DataSource dataSource) {
              return new JdbcTemplate(dataSource);
          }
      
      }
      

      【讨论】:

        猜你喜欢
        • 2013-12-23
        • 1970-01-01
        • 2017-02-24
        • 1970-01-01
        • 2020-03-15
        • 2018-08-29
        • 2017-10-15
        • 2023-03-17
        • 1970-01-01
        相关资源
        最近更新 更多