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}