Spring Boot服务器不断达到Postgres连接限制

时间:2016-07-28 23:17:34

标签: java spring postgresql

我有一个简单的弹簧启动应用程序。它的运作方式如下:

  • 用户进行REST查询
  • 在数据库中查找
  • 返回结果

我得到的问题是,在发出约97个请求后,我收到消息:

FATAL: remaining connection slots are reserved for non-replication superuser connections

我的Postgres服务器有100个连接限制,因此对于超级用户有3个,97是有意义的。我很困惑的是为什么Spring Boot不会自动关闭我的连接,尽管我已经被认为应该根据其他S / O帖子。

以下是我的REST端点的代码:

@RestController
@RequestMapping(value = "/myEndpoint")
public class CommentController {

    @Autowired
    // Where the business logic is
    private CommentJdbcService commentJdbcService;

    @Autowired
    private JdbcTemplate template;

    @ApiOperation(value = "Get a comment by ID")
    @RequestMapping(value = "/{comment_id}", produces = "application/json", method = RequestMethod.GET)
    public ResponseEntity getComment(@PathVariable String commentId) {
        List<Comment> result;
        try {
            result = commentJdbcService.get(comment_id, template.getDataSource().getConnection());
        } catch (Exception e) {
            return log(e, HttpStatus.INTERNAL_SERVER_ERROR, slf4jLogger, Error.Levels.ERROR);
        }
        return new ResponseEntity<>(result, HttpStatus.OK);
    }
}

这是我的业务逻辑的代码:

@Service
public class CommentJdbcService {
    public List<Comment> get(String commentId, Connection connection) throws Exception {
        String getSql = "SELECT * FROM comment WHERE comment_id=?::UUID";
        PreparedStatement statement = connection.prepareStatement(getSql);
        statement.setString(1, commentId);
        List<Comment> comments = new ArrayList<>();
        ResultSet assetResult = statement.executeQuery();
        while (assetResult.next()){
            comments.add(build(assetResult, connection));
        }
        return comments;
    }
}

基于此,为什么Spring Spring会自动关闭我的连接?

1 个答案:

答案 0 :(得分:0)

最佳做法是在完成连接后关闭连接:

@ApiOperation(value = "Get a comment by ID")
@RequestMapping(value = "/{comment_id}", produces = "application/json", method = RequestMethod.GET)
public ResponseEntity getComment(@PathVariable String commentId) {
    List<Comment> result;
    Connection con;
    try {
        con = template.getDataSource().getConnection();
        result = commentJdbcService.get(comment_id, con);
    } catch (Exception e) {
        return log(e, HttpStatus.INTERNAL_SERVER_ERROR, slf4jLogger, Error.Levels.ERROR);
    } finally {
        try {
            if (con != null)
                con.close();
        } catch(SQLException se) {
            se.printStackTrace();
        }
    }
    return new ResponseEntity<>(result, HttpStatus.OK);
}

还有你准备好的陈述和结果集:

@Service
public class CommentJdbcService {
    public List<Comment> get(String commentId, Connection connection) throws Exception {
        PreparedStatement statement;
        ResultSet assetResult;
        try {
            String getSql = "SELECT * FROM comment WHERE comment_id=?::UUID";
            statement = connection.prepareStatement(getSql);
            statement.setString(1, commentId);
            List<Comment> comments = new ArrayList<>();
            assetResult = statement.executeQuery();
            while (assetResult.next()){
                comments.add(build(assetResult, connection));
            }
            return comments;
        } catch (Exception e) {
            // do exception handling
        } finally {
            try {
                if (statement != null)
                    statement.close();
            } catch(SQLException se) {
                se.printStackTrace();
            }
            try {
                if (assetResult != null)
                    assetResult.close();
            } catch(SQLException se) {
                se.printStackTrace();
            }
        }
    }
}