☰ Mục lục series
Tài liệu Go tiếng Việt
  1. Bắt đầu (Getting started)
    1. Tổng quan
    2. Tải về và cài đặt
    3. Bắt đầu với Go
    4. Quản lý các bản cài đặt Go
    5. Plugin trình soạn thảo và IDE
  2. Dạo quanh Go (A Tour of Go)
    1. Chào mừng
    2. Package, biến và hàm
    3. Điều khiển luồng
    4. Struct, slice và map
    5. Method và interface
    6. Generics
    7. Xử lý đồng thời
  3. Hướng dẫn (Tutorials)
    1. Danh sách hướng dẫn
    2. Tạo một Go module
    3. Gọi mã của bạn từ một module khác
    4. Trả về và xử lý lỗi
    5. Trả về lời chào ngẫu nhiên
    6. Trả về lời chào cho nhiều người
    7. Thêm một test
    8. Biên dịch và cài đặt ứng dụng
    9. Kết luận
    10. Bắt đầu với workspace nhiều module
    11. Phát triển RESTful API với Go và Gin
    12. Truy cập cơ sở dữ liệu quan hệ
    13. Bắt đầu với generics
    14. Bắt đầu với fuzzing
    15. Làm việc với JSON
    16. Tìm và sửa các dependency có lỗ hổng với govulncheck
    17. Tìm và khắc phục phụ thuộc có lỗ hổng với VS Code Go
    18. Viết ứng dụng web
  4. Viết code Go
    1. Cách viết mã Go
    2. Effective Go
    3. Doc Comment trong Go
  5. Module
    1. Phát triển và publish module
    2. Quản lý phụ thuộc
    3. Tổ chức một module Go
    4. Quản lý mã nguồn của module
    5. Cách đánh số phiên bản module
    6. Quy trình phát hành và đánh phiên bản module
    7. Publish một module
    8. Phát triển một bản cập nhật major version
    9. Tham chiếu tệp go.mod
    10. Ngừng hỗ trợ 'go get' cho việc cài đặt tệp thực thi
  6. Cơ sở dữ liệu (Database)
    1. Truy cập cơ sở dữ liệu quan hệ
    2. Mở một handle cơ sở dữ liệu
    3. Thực thi câu lệnh SQL không trả về dữ liệu
    4. Truy vấn dữ liệu
    5. Dùng prepared statement
    6. Thực thi transaction
    7. Huỷ các thao tác đang chạy
    8. Quản lý kết nối
    9. Tránh rủi ro SQL injection
  7. Chẩn đoán và hiệu năng
    1. Chẩn đoán
    2. Hướng dẫn về Go Garbage Collector
    3. Tối ưu hoá dựa trên profile
    4. Data Race Detector
    5. Gỡ lỗi mã Go bằng GDB
    6. Hỗ trợ coverage profiling cho integration test
  8. Bảo mật (Security)
    1. Tổng quan bảo mật
    2. Thực hành tốt về bảo mật cho lập trình viên Go
    3. Quản lý lỗ hổng trong Go
    4. Cơ sở dữ liệu lỗ hổng của Go
    5. Quét lỗ hổng trong IDE
    6. Chính sách CNA của Go
    7. Go Fuzzing
    8. Chi tiết kỹ thuật của Go Fuzzing
    9. Chính sách bảo mật của Go
    10. Threat Model của Go
    11. Các quyết định về bảo mật của Go
    12. Tuân thủ FIPS 140-3
  9. Công cụ và toolchain
    1. Tài liệu về các lệnh
    2. Về lệnh go
    3. Go Toolchains
    4. Telemetry của Go
    5. Cài đặt Go từ mã nguồn
    6. Cài đặt và sử dụng gccgo
  10. Tham khảo
    1. Câu hỏi thường gặp (FAQ)
    2. Go 1 và tương lai của các chương trình Go
    3. Hướng dẫn chuyển đổi sang encoding/json/v2
    4. Hướng dẫn đóng góp
    5. Đóng góp cho frontend gccgo
  11. Phụ lục
    1. Bảng thuật ngữ
Cơ sở dữ liệu (Database)

Quản lý kết nối

Bản dịch từ go.dev/doc/database/manage-connections

Với phần lớn chương trình, bạn không cần chỉnh các giá trị mặc định của connection pool sql.DB. Nhưng với một số chương trình nâng cao, bạn có thể cần tinh chỉnh các tham số của connection pool hoặc làm việc trực tiếp với các kết nối. Chủ đề này giải thích cách làm.

Handle cơ sở dữ liệu sql.DB an toàn khi được nhiều goroutine dùng đồng thời (nghĩa là handle này chính là thứ mà các ngôn ngữ khác có thể gọi là “thread-safe”). Một số thư viện truy cập cơ sở dữ liệu khác lại dựa trên các kết nối chỉ dùng được cho một thao tác tại một thời điểm. Để lấp khoảng cách đó, mỗi sql.DB quản lý một pool các kết nối đang hoạt động tới cơ sở dữ liệu bên dưới, tạo thêm kết nối mới khi cần cho tính song song trong chương trình Go của bạn.

Connection pool phù hợp với hầu hết nhu cầu truy cập dữ liệu. Khi bạn gọi method Query hoặc Exec của sql.DB, phần hiện thực của sql.DB sẽ lấy một kết nối khả dụng từ pool, hoặc tạo một kết nối mới nếu cần. Package trả kết nối về lại pool khi không cần đến nó nữa. Cơ chế này hỗ trợ mức độ song song cao khi truy cập cơ sở dữ liệu.

Thiết lập thuộc tính connection pool

Bạn có thể thiết lập các thuộc tính chi phối cách package sql quản lý một connection pool. Để lấy thống kê về tác động của các thuộc tính này, hãy dùng DB.Stats.

Thiết lập số kết nối mở tối đa

DB.SetMaxOpenConns áp một giới hạn lên số kết nối đang mở. Vượt quá giới hạn này, các thao tác cơ sở dữ liệu mới sẽ chờ một thao tác hiện có kết thúc, và khi đó sql.DB sẽ tạo thêm một kết nối khác. Theo mặc định, sql.DB tạo một kết nối mới bất cứ khi nào cần một kết nối mà toàn bộ các kết nối hiện có đều đang bận.

Hãy nhớ rằng việc đặt giới hạn khiến việc dùng cơ sở dữ liệu giống như phải giành một khoá hay semaphore, hệ quả là ứng dụng của bạn có thể deadlock khi chờ một kết nối cơ sở dữ liệu mới.

Thiết lập số kết nối nhàn rỗi tối đa

DB.SetMaxIdleConns thay đổi giới hạn về số lượng kết nối nhàn rỗi tối đa mà sql.DB duy trì.

Khi một thao tác SQL kết thúc trên một kết nối cơ sở dữ liệu nào đó, thông thường kết nối không bị đóng ngay lập tức: ứng dụng có thể sẽ sớm cần đến nó lần nữa, và việc giữ kết nối đang mở giúp tránh phải kết nối lại tới cơ sở dữ liệu cho thao tác kế tiếp. Theo mặc định, tại mỗi thời điểm một sql.DB giữ hai kết nối nhàn rỗi. Nâng giới hạn này lên có thể tránh việc kết nối lại thường xuyên trong những chương trình có mức song song đáng kể.

Thiết lập thời gian tối đa một kết nối được nhàn rỗi

DB.SetConnMaxIdleTime đặt khoảng thời gian tối đa mà một kết nối có thể nhàn rỗi trước khi bị đóng. Nó khiến sql.DB đóng những kết nối đã nhàn rỗi lâu hơn khoảng thời gian cho trước.

Theo mặc định, khi một kết nối nhàn rỗi được đưa vào connection pool, nó sẽ nằm đó cho tới khi lại được cần đến. Khi dùng DB.SetMaxIdleConns để tăng số kết nối nhàn rỗi được phép trong những đợt hoạt động song song dồn dập, việc dùng thêm DB.SetConnMaxIdleTime có thể sắp xếp giải phóng các kết nối đó về sau, lúc hệ thống đã rảnh rỗi.

Thiết lập vòng đời tối đa của kết nối

Dùng DB.SetConnMaxLifetime để đặt khoảng thời gian tối đa mà một kết nối có thể được giữ mở trước khi bị đóng.

Theo mặc định, một kết nối có thể được dùng và dùng lại trong khoảng thời gian dài tuỳ ý, với điều kiện tuân theo các giới hạn mô tả ở trên. Trong một số hệ thống, chẳng hạn những hệ thống dùng máy chủ cơ sở dữ liệu có cân bằng tải, việc bảo đảm ứng dụng không bao giờ dùng một kết nối cụ thể quá lâu mà không kết nối lại có thể sẽ hữu ích.

Dùng kết nối riêng

Package database/sql bao gồm các hàm bạn có thể dùng khi cơ sở dữ liệu có thể gán một ý nghĩa ngầm định cho một chuỗi thao tác được thực thi trên một kết nối cụ thể.

Ví dụ thường gặp nhất là transaction, vốn thường bắt đầu bằng lệnh BEGIN, kết thúc bằng lệnh COMMIT hoặc ROLLBACK, và gộp mọi lệnh được phát ra trên kết nối đó giữa hai lệnh trên vào cùng một transaction tổng thể. Với trường hợp này, hãy dùng phần hỗ trợ transaction của package sql. Xem Thực thi transaction.

Với những trường hợp khác mà một chuỗi các thao tác riêng lẻ đều phải được thực thi trên cùng một kết nối, package sql cung cấp các kết nối riêng. DB.Conn lấy một kết nối riêng, tức là một sql.Conn. sql.Conn có các method BeginTx, ExecContext, PingContext, PrepareContext, QueryContext, và QueryRowContext hoạt động giống các method tương ứng trên DB nhưng chỉ dùng kết nối riêng đó. Khi đã dùng xong kết nối riêng, mã của bạn phải giải phóng nó bằng Conn.Close.

Nội dung gốc: Go Documentation © The Go Authors, giấy phép CC BY 3.0. Bản dịch và ghi chú: Lê Văn Dũng.