spring-boot - com.microsoft.sqlserver.jdbc.sqlserver异常 : the stream is closed

标签 spring-boot hibernate sql-server-2012 hikaricp mssql-jdbc

我正在使用mssql-jdbc-12.2.0.jre8.jarHikariCP-4.0.3.jar连接到 Microsoft SQL Server 数据库

SQL Server 版本是:Microsoft SQL Server 2012 - 11.0.5548.0 (X64) Sep 6 2014 17:19:28 Copyright (c) Microsoft Corporation Enterprise Edition (64-bit) on Windows NT 6.3 <X64> (Build 9600: ) (Hypervisor)

hibernate 版本:hibernate-core-5.6.11.Final

JRE版本:jre1.8.0_281

Apache Tomcat 版本:9.0.71

Springboot版本:2.7.4

Spring 数据源配置:

spring.datasource.url=jdbc:sqlserver://mydatabaseServer:51803;databaseName=mydatabaseName;encrypt=false;trustServerCertificate=true;socketTimeout=60000
spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.datasource.password = mypassword
spring.datasource.testWhileIdle = true
spring.datasource.test-on-borrow=true
spring.datasource.validationQuery = SELECT 1
spring.datasource.sql-script-encoding=UTF-8
spring.datasource.username = myusername
spring.datasource.hikari.pool-name=myPool
spring.datasource.hikari.maximum-pool-size=300
spring.datasource.hikari.connectionTimeout=80000 
spring.datasource.hikari.max-lifetime=300000
spring.datasource.hikari.idle-timeout=60000
spring.datasource.hikari.leakDetectionThreshold=300000
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.SQLServer2012Dialect
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
spring.jpa.open-in-view=false
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy

导致问题的查询返回最多 10 行,如下所示:

@Repository
@Transactional(readOnly = true)
@Log4j2
public class SearchService {

    @PersistenceContext
    private EntityManager entityManager;
    
    public List<Request> searchRequests(SearchModel searchModel, int pageNumber) {
    

        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
        CriteriaQuery<Request> criteriaQuery = criteriaBuilder.createQuery(Request.class);
        Root<Request> requestRoot = criteriaQuery.from(Request.class);
        requestRoot.alias("r");
        
        Predicate predicate = createConditions(requestRoot, criteriaBuilder, searchModel);
        criteriaQuery.select(requestRoot);
        Order orderBy = criteriaBuilder.desc(requestRoot.get("id"));
        String orderByProperty = searchModel.getOrderBy();
        criteriaQuery.where(predicate).orderBy(orderBy);

        // pageSize is 10
        // searchModel.getMaxResult() = 10
        // for pageNumber 1 startFrom will be 0 and maxResult will be 10
        int startFrom = (pageNumber - 1) * searchModel.getPageSize();
        List<Request> result = entityManager.createQuery(criteriaQuery).setMaxResults(searchModel.getMaxResult())
                .setFirstResult(startFrom).getResultList();
        return result;
    
    }
    

}

上面的设置长期以来工作正常,但最近有时我会遇到很多以下异常:com.microsoft.sqlserver.jdbc.sqlserverexception: the stream is closed 上线:

entityManager.createQuery(criteriaQuery).setMaxResults(searchModel.getMaxResult())
                    .setFirstResult(startFrom).getResultList();

这被翻译为:

SELECT * FROM request ORDER BY id OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY;

直接从 SQL Server 执行此查询时需要 10 毫秒 当流关闭时发生问题时,在监视工具中我可以看到它在此查询中多次关闭!

注意:我从中选择的请求实体/表没有 Eager 关系并且没有二进制列但是它有两个 varchar(MAX) 列并且达到的最大长度为 5368

什么可能导致此问题?可能是应用程序相关或数据库/Windows 服务器问题?

最佳答案

“流已关闭”异常......相当模糊。

假设没有网络问题,并且 SQL Server 日志没有显示任何其他更详细的错误消息,或者服务器本身没有 CPU/内存/磁盘空间问题,您可能会考虑:

  • 查看您的HikariCP connection pool settings 。您可能需要调整 max-lifetimeidle-timeoutleakDetectionThreshold 设置,以确保连接不会过早关闭或保持太久。太长了。

  • 优化您的查询:虽然直接在 SQL Server 上执行时查询本身似乎表现良好,但您仍然可以通过向 Request 添加适当的索引来尝试进一步优化查询表或使用更有效的方法进行分页,例如使用基于键集的分页。

还 try catch 更多详细信息的异常,例如(来自“How to catch Hibernate SQL EXCEPTIONS IN SPRING ”):

import javax.persistence.PersistenceException;
import org.hibernate.exception.JDBCConnectionException;
import org.springframework.dao.DataAccessException;

@Repository
@Transactional(readOnly = true)
@Log4j2
public class SearchService {

    @PersistenceContext
    private EntityManager entityManager;

    public List<Request> searchRequests(SearchModel searchModel, int pageNumber) {
        List<Request> result = new ArrayList<>();

        try {
            CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
            CriteriaQuery<Request> criteriaQuery = criteriaBuilder.createQuery(Request.class);
            Root<Request> requestRoot = criteriaQuery.from(Request.class);
            requestRoot.alias("r");

            Predicate predicate = createConditions(requestRoot, criteriaBuilder, searchModel);
            criteriaQuery.select(requestRoot);
            Order orderBy = criteriaBuilder.desc(requestRoot.get("id"));
            String orderByProperty = searchModel.getOrderBy();
            criteriaQuery.where(predicate).orderBy(orderBy);

            int startFrom = (pageNumber - 1) * searchModel.getPageSize();
            result = entityManager.createQuery(criteriaQuery).setMaxResults(searchModel.getMaxResult())
                    .setFirstResult(startFrom).getResultList();
        } catch (PersistenceException | DataAccessException e) {
            if (e.getCause() instanceof JDBCConnectionException) {
                log.error("JDBC connection exception occurred: {}", e.getMessage(), e);
            } else {
                log.error("An exception occurred while executing the search query: {}", e.getMessage(), e);
            }
        } catch (Exception e) {
            log.error("An unexpected exception occurred while executing the search query: {}", e.getMessage(), e);
        }

        return result;
    }
}

我已将查询执行包装在 try-catch block 中,以捕获任何 PersistenceExceptionDataAccessException 或其他常规异常。如果发生JDBCConnectionException,则会记录一条特定消息。对于其他异常,将记录更通用的错误消息。
这应该可以帮助您识别和诊断查询执行期间可能发生的任何问题。

关于spring-boot - com.microsoft.sqlserver.jdbc.sqlserver异常 : the stream is closed,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76411787/

相关文章:

spring - Spring WebFlux 中的 ReactiveSecurityContextHolder 为空

java - 在 Spring Boot 应用程序中记录有关 JDBC 连接的信息

mysql - Hibernate建表不成功,sql语法错误

java - 如何使受管实体具有上下文感知能力?

sql-server - 列中的循环 IDENTITY 编号

python - 为什么我的 VARCHAR 被截断为 255 个字符?我该如何解决?

java - Spring继承@Component并带有构造函数参数

spring-boot - 配置 Spring WebFlux WebClient 以使用自定义线程池

java - 从实现类覆盖自定义 jar 文件中的配置属性时,entityManagerFactory 中出现错误

SQL Server IF EXISTS THEN 1 ELSE 2