Belajar Database di Go: Driver, Connection Pool, dan 3 Hal yang Sering Salah
Waktu pertama kali belajar database di Go, saya kira tinggal panggil sql.Open() dan selesai. 3 jam kemudian , aplikasi tidak connect, error tidak jelas. Ternyata masalahnya simpel: lupa install driver. Artikel ini membahas 3 hal yang sering salah: sql.Open bukan connect, sql.DB itu pool bukan koneksi, dan QueryContext mengunci koneksi.
Waktu pertama kali belajar database di Go, saya kira tinggal panggil sql.Open() dan selesai. 3 jam kemudian , aplikasi tidak connect, error tidak jelas, dan saya bingung harus berbuat apa.
Ternyata masalahnya simpel: saya lupa install driver MySQL. Go tidak punya driver database bawaan , anda harus eksplisit memberi tahu database apa yang dipakai. Berasa sepele, tapi ini fundamental yang sering dilompatin tutorial.
Artikel ini saya tulis khusus buat yang baru mulai pakai database di Go , dari koneksi sampai connection pool, dari yang sering salah sampai yang benar.
Driver: Pilih Database, Install Driver-nya
Package database/sql adalah abstraction layer. Dia menyediakan interface seragam untuk semua SQL database. Tapi untuk connect ke database tertentu (MySQL, PostgreSQL, SQLite), anda butuh driver spesifik.
Cara install driver: cukup import dengan blank identifier , efek sampingnya saja yang dibutuhkan (registrasi driver ke database/sql).
Daftar driver: https://go.dev/wiki/SQLDrivers
Koneksi: sql.Open() Bukan Buat Connect
Kesalahan saya: mengira sql.Open() itu bikin koneksi dan connect ke database. Padahal sql.Open() cuma bikin pool object , koneksi beneran terjadi saat anda execute query pertama.
Ini penting karena sql.Open() tidak akan return error kalau database-nya mati. Error connection baru muncul saat anda panggil .Ping() atau .Query().
Jangan lupa close db saat aplikasi mati. Tapi jangan close tiap selesai query , db.Close() nutup seluruh pool, bukan satu koneksi.
Connection Pool: sql.DB Itu Bukan Satu Koneksi
Poin yang paling sering disalahpaham: sql.DB itu mengelola pool koneksi, bukan satu koneksi. Saat anda query, diambil satu koneksi dari pool. Saat selesai, dikembalikan. Pool ini thread-safe , aman dipakai dari banyak goroutine.
Tapi pool harus dikonfigurasi. Default-nya tidak ada batas maksimal koneksi , kalau lupa set MaxOpenConns dan aplikasi spike, database bisa kebanjiran.
Pengalaman saya: lupa set MaxOpenConns, aplikasi kena spike request, database MySQL connection limit exceeded. Service down 10 menit.
DML vs DQL: ExecContext vs QueryContext
Go punya dua cara execute query, dan memilih yang salah bisa bikin connection leak.
DML (INSERT, UPDATE, DELETE) , pakai ExecContext
ExecContext mengembalikan sql.Result (RowsAffected, LastInsertId). Tidak mengunci koneksi , langsung balik ke pool setelah execute.
DQL (SELECT) , pakai QueryContext
QueryContext mengunci satu koneksi dari pool sampai anda panggil rows.Close(). Kalau lupa close, koneksi hilang dari pool , bisa habis.
Best Practice: Pattern GetUsers yang Aman
Gabungin semua pelajaran di atas: context untuk timeout, scan dengan error handling, dan , jangan lupa , defer rows.Close().
Kesimpulan: 3 Hal yang Sering Salah
- sql.Open bukan connect , pakai Ping() untuk verifikasi
- sql.DB itu pool, bukan koneksi , konfigurasi MaxOpenConns biar tidak kebanjiran
- QueryContext mengunci koneksi , jangan lupa rows.Close()
3 pelajaran ini saya bayar dengan 1 production incident + 3 jam debugging. Anda tidak perlu.
Referensi
1. Go SQLDrivers , Daftar Driver Database untuk Go
