一文理清database/sql包你可能遇到的問題
- 那么database/sql包實現了什么功能呢?
- 建立數據庫連接
- 檢測連接是否能ping通
- 通過連接進行具體的sql查詢
- 查詢完將連接進行關閉
- 當數據庫宕掉重啟后再次查詢
- database/sql包創建的db連接 對于數據庫宕掉后重啟是否仍然有效?
當你點開這篇文章的時候你應該是想用go來與數據庫進行交互的咯,那么正常流程下,你會涉及到建立數據庫連接、檢測連接是否能ping通、通過連接進行具體的sql查詢,查詢完將連接進行關閉,當數據庫宕掉重啟后再次查詢等等。下面對于這些實現都會有介紹。
那么database/sql包實現了什么功能呢?
我們來看一下官方的答案。
Go語言中的database/sql
包提供了一套與數據庫進行交互的統一編程接口。它的主要功能和特性可以總結為以下幾點:
- 統一的編程接口:
database/sql
包通過提供一組統一的API,如Prepare()
,Exec()
,Query()
等,使得開發人員能夠以相同的方式操作不同的數據庫。這大大提高了代碼的可移植性和靈活性。 - 驅動支持:
database/sql
包本身并不直接與數據庫通信,而是依賴于第三方數據庫驅動程序。這些驅動程序需要實現database/sql/driver
包中定義的Driver
接口,并在程序初始化階段通過sql.Register()
方法注冊到database/sql
中。常見的關系型數據庫如MySQL、PostgreSQL、Oracle、Gbase8s等都有對應的Go語言驅動程序。比如oracle的驅動mattn/go-oci8: Oracle driver for Go using database/sql (github.com) - 連接池管理:
database/sql
維護了一個數據庫連接池,用于管理數據庫連接。當通過sql.Open()
打開一個數據庫連接時,database/sql
會在合適的時機調用注冊的驅動來創建一個具體的連接,并將其添加到連接池中。連接池會負責連接的復用、管理和維護工作,并且這是并發安全的。 - 事務支持:
database/sql
包還支持事務處理,可以通過Tx
類型的方法如Begin()
,Commit()
,Rollback()
等來進行事務的管理。 - 安全性:為了防止SQL注入攻擊,
database/sql
包推薦使用預編譯語句和參數化查詢。這樣可以確保所有的SQL語句在執行前都會被預先分析和編譯,從而避免了潛在的安全問題。
建立數據庫連接
package demoimport ("database/sql"
)var mydb,_ = sql.Open("mysql","connection_string")
檢測連接是否能ping通
err = db.Ping()
if err != nil {panic(err)
}
通過連接進行具體的sql查詢
func testSelect(db *sql.DB) error {rows, err := db.Query("select 3.14, 'foo' from dual")if err != nil {return err}defer rows.Close()for rows.Next() {var f1 float64var f2 stringrows.Scan(&f1, &f2)println(f1, f2) // 3.14 foo}return nil
}
//當然 對于不同的查詢需求使用的函數不一樣 這里就當你使用的時候直接去搜就好啦
//比如 需要返回值時
var primary string
err := c.db.QueryRow("select ha_primary from sysha_type").Scan(&primary)
查詢完將連接進行關閉
db.Close()
當數據庫宕掉重啟后再次查詢
if err = testSelect(db); err != nil {fmt.Println(err)return}
大家應該發現了再次查詢和查詢語句是一樣的。其實對于執行上,都是執行的查詢語句。但是我們需要考慮的是經歷過數據庫宕掉之后,還是傳原來的db嗎?那么就引出下一個問題。
database/sql包創建的db連接 對于數據庫宕掉后重啟是否仍然有效?
當數據庫宕掉后重啟,原先由database/sql包創建的db連接并不會自動恢復其有效性。在Go語言中,database/sql
包提供了與SQL數據庫進行交互的功能,其中包括連接池的管理。連接池負責維護打開的數據庫連接,以便在多個數據庫操作之間重用這些連接,從而提高應用程序的性能。然而,當數據庫宕機并重新啟動后,原有的數據庫連接將不再有效,需要重新建立連接。以下是具體分析:
- 數據庫連接狀態檢測:
- 在正常情況下,
database/sql
的連接池會維護一定數量的活躍和空閑連接。 db.SetMaxIdleConns()
用于設置連接池中空閑連接的最大數量。db.SetMaxOpenConns()
用于設置到數據庫的同時最大打開連接數。db.SetConnMaxLifetime()
可以設置連接的最大生命周期,超過這個時間,連接將被關閉并從池中移除。
- 在正常情況下,
- 數據庫宕機影響:
- 當數據庫宕機時,所有現有的數據庫連接將會失效。
- 即使數據庫隨后重啟,這些失效的連接也不會自動恢復其有效性。
- 數據庫重啟處理:
- 在數據庫重啟后,必須創建新的數據庫連接以替換失效的連接。
database/sql
包本身不提供自動重連功能,因此需要在應用程序邏輯中處理這種情況。
- 連接池參數配置:
- 通過合理配置連接池參數,如最大空閑連接數、最大打開連接數和連接最大生命周期,可以優化數據庫連接的使用效率。
- 這些參數的設置應根據應用程序的具體需求和數據庫的實際性能進行調整。
- 異常情況處理:
- 應用程序應具備異常處理機制,能夠在數據庫不可用時進行適當的錯誤處理和重試邏輯。
- 可以考慮實現自定義的重連策略,例如指數退避算法,以避免在數據庫重啟期間過多地嘗試連接。
- 測試與驗證:
- 在開發過程中,應通過模擬數據庫宕機和重啟的場景來測試應用程序的異常處理能力。
- 確保在實際部署前,應用程序能夠正確處理數據庫連接失效的情況。
所以,正確的執行步驟應該是,ping時發現db連接失效了,不通了,執行close操作,再次使用Open打開新的連接,ping檢查db連接是否有效,再進行查詢。