☰ 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)

Huỷ các thao tác đang chạy

Bản dịch từ go.dev/doc/database/cancel-operations

Bạn có thể quản lý các thao tác đang chạy bằng context.Context của Go. Context là một giá trị dữ liệu chuẩn của Go, có khả năng cho biết thao tác tổng thể mà nó đại diện đã bị huỷ và không còn cần thiết nữa hay chưa. Bằng cách truyền một context.Context qua các lệnh gọi hàm và các dịch vụ trong ứng dụng, những thành phần đó có thể dừng làm việc sớm và trả về lỗi khi phần xử lý của chúng không còn cần đến nữa. Tìm hiểu thêm về Context tại Go Concurrency Patterns: Context.

Ví dụ, bạn có thể muốn:

  • Kết thúc những thao tác chạy lâu, bao gồm các thao tác cơ sở dữ liệu mất quá nhiều thời gian để hoàn thành.
  • Lan truyền các yêu cầu huỷ đến từ nơi khác, chẳng hạn khi một client đóng kết nối.

Nhiều API dành cho lập trình viên Go có các hàm nhận đối số Context, giúp bạn dùng Context xuyên suốt ứng dụng của mình dễ dàng hơn.

Huỷ thao tác cơ sở dữ liệu sau một timeout

Bạn có thể dùng Context để đặt một timeout hoặc deadline, sau mốc đó thao tác sẽ bị huỷ. Để tạo ra một Context có timeout hoặc deadline, hãy gọi context.WithTimeout hoặc context.WithDeadline.

Mã trong ví dụ về timeout dưới đây tạo ra một Context rồi truyền nó vào method QueryContext của sql.DB.

func QueryWithTimeout(ctx context.Context) {
	// Create a Context with a timeout.
	queryCtx, cancel := context.WithTimeout(ctx, 5*time.Second)
	defer cancel()

	// Pass the timeout Context with a query.
	rows, err := db.QueryContext(queryCtx, "SELECT * FROM album")
	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()

	// Handle returned rows.
}

Khi một context được dẫn xuất từ một context bên ngoài, như queryCtx được dẫn xuất từ ctx trong ví dụ này, thì nếu context bên ngoài bị huỷ, context dẫn xuất cũng tự động bị huỷ theo. Ví dụ, trong các máy chủ HTTP, method http.Request.Context trả về một context gắn với request đó. Context ấy sẽ bị huỷ nếu client HTTP ngắt kết nối hoặc huỷ request HTTP (điều này khả thi trong HTTP/2). Truyền context của một request HTTP vào QueryWithTimeout ở trên sẽ khiến truy vấn cơ sở dữ liệu dừng sớm khi toàn bộ request HTTP bị huỷ, hoặc khi truy vấn chạy quá năm giây.

Lưu ý: Luôn defer lệnh gọi hàm cancel được trả về khi bạn tạo một Context mới có timeout hoặc deadline. Việc này giải phóng các tài nguyên mà Context mới đang giữ khi hàm chứa nó kết thúc. Nó cũng huỷ luôn queryCtx, nhưng tới lúc hàm trả về thì lẽ ra không còn gì đang dùng queryCtx nữa.

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.