Phân tích pool kết nối trong series MyBatis - 228kbet

Pool kết nối 228kbet hoạt động dựa trên hai luồng logic chính, đầu tiên là logic lấy kết nối. Hãy cùng Trang Cá Cược xem xét đoạn mã sau đây để hiểu rõ kết quả tỷ số hơn.

  1private PooledConnection popConnection(String username, String password) throws SQLException {  
  2    boolean countedWait = false;  
  3    PooledConnection conn = null;  
  4    long t = System.currentTimeMillis();  
  5    int localBadConnectionCount = 0;  
  6
  7    // Vòng lặp liên tục để đảm bảo có thể lấy được kết nối  
  8    while (conn == null) {  
  9        lock.lock(); // Khóa tài nguyên để tránh xung đột giữa các luồng  
 10        try {  
 11            if (!state.idleConnections.isEmpty()) {  
 12                // Nếu danh sách kết nối rảnh không trống  
 13                conn = state.idleConnections.remove(0);  
 14                if (log.isDebugEnabled()) {  
 15                    log.debug("Kết nối " + conn.getRealHashCode() + " đã được kiểm tra từ pool.");  
 16                }  
 17            } else {  
 18                // Trường hợp không có kết nối rảnh  
 19                if (state.activeConnections.size() < poolMaximumActiveConnections) {  
 20                    // Có thể tạo kết nối mới nếu số lượng kết nối đang hoạt động nhỏ hơn giới hạn tối đa  
 21                    conn = new PooledConnection(dataSource.getConnection(), this);  
 22                    if (log.isDebugEnabled()) {  
 23                        log.debug("Tạo kết nối mới " + conn.getRealHashCode() + ".");  
 24                    }  
 25                } else {  
 26                    // Không thể tạo kết nối mới  
 27                    PooledConnection oldestActiveConnection = state.activeConnections.get(0);  
 28                    long longestCheckoutTime = oldestActiveConnection.getCheckoutTime();  
 29                    if (longestCheckoutTime > poolMaximumCheckoutTime) {  
 30                        // Kết nối quá thời gian cho phép sử dụng  
 31                        state.claimedOverdueConnectionCount++;  
 32                        state.accumulatedCheckoutTimeOfOverdueConnections += longestCheckoutTime;  
 33                        state.accumulatedCheckoutTime += longestCheckoutTime;  
 34                        state.activeConnections.remove(oldestActiveConnection);  
 35                        if (!oldestActiveConnection.getRealConnection().getAutoCommit()) {  
 36                            try {  
 37                                oldestActiveConnection.getRealConnection().rollback();  
 38                            } catch (SQLException e) {  
 39                                log.debug("Không thể hoàn tác kết nối xấu.");  
 40                            }  
 41                        }  
 42                        conn = new PooledConnection(oldestActiveConnection.getRealConnection(), this);  
 43                        conn.setCreatedTimestamp(oldestActiveConnection.getCreatedTimestamp());  
 44                        conn.setLastUsedTimestamp(oldestActiveConnection.getLastUsedTimestamp());  
 45                        oldestActiveConnection.invalidate();  
 46                        if (log.isDebugEnabled()) {  
 47                            log.debug("Lấy lại kết nối quá hạn " + conn.getRealHashCode() + ".");  
 48                        }  
 49                    } else {  
 50                        // Cần chờ đợi nếu không thể tìm thấy hoặc tạo kết nối  
 51                        try {  
 52                            if (!countedWait) {  
 53                                state.hadToWaitCount++;  
 54                                countedWait = true;  
 55                            }  
 56                            if (log.isDebugEnabled()) {  
 57                                log.debug("Chờ đến " + poolTimeToWait + " mili giây để lấy kết nối.");  
 58                            }  
 59                            long wt = System.currentTimeMillis();  
 60                            condition.await(poolTimeToWait, TimeUnit.MILLISECONDS);  
 61                            state.accumulatedWaitTime += System.currentTimeMillis() - wt;  
 62                        } catch (InterruptedException e) {  
 63                            Thread.currentThread().interrupt();  
 64                            break;  
 65                        }  
 66                    }  
 67                }  
 68            }  
 69
 70            if (conn != null) {  
 71                if (conn.isValid()) {  
 72                    if (!conn.getRealConnection().getAutoCommit()) {  
 73                        conn.getRealConnection().rollback();  
 74                    }  
 75                    conn.setConnectionTypeCode(assembleConnectionTypeCode(dataSource.getUrl(), username, password));  
 76                    conn.setCheckoutTimestamp(System.currentTimeMillis());  
 77                    conn.setLastUsedTimestamp(System.currentTimeMillis());  
 78                    state.activeConnections.add(conn);  
 79                    state.requestCount++;  
 80                    state.accumulatedRequestTime += System.currentTimeMillis() - t;  
 81                } else {  
 82                    if (log.isDebugEnabled()) {  
 83                        log.debug("Một kết nối xấu (" + conn.getRealHashCode() + ") đã được trả về từ pool, thử kết nối khác.");  
 84                    }  
 85                    state.badConnectionCount++;  
 86                    localBadConnectionCount++;  
 87                    conn = null;  
 88                    if (localBadConnectionCount > (poolMaximumIdleConnections + poolMaximumLocalBadConnectionTolerance)) {  
 89                        throw new SQLException("PooledDataSource: Không thể lấy một kết nối tốt tới cơ sở dữ liệu.");  
 90                    }  
 91                }  
 92            }  
 93        } finally {  
 94            lock.unlock();  
 95        }  
 96    }  
 97
 98    if (conn == null) {  
 99        throw new SQLException("PooledDataSource: Lỗi nghiêm trọng không xác định. Pool kết nối trả về giá trị null.");  
100    }  
101    return conn;  
102}