sqlmanager.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. package sqlx
  2. import (
  3. "database/sql"
  4. "io"
  5. "sync"
  6. "time"
  7. "github.com/tal-tech/go-zero/core/syncx"
  8. )
  9. const (
  10. maxIdleConns = 64
  11. maxOpenConns = 64
  12. maxLifetime = time.Minute
  13. )
  14. var connManager = syncx.NewResourceManager()
  15. type pingedDB struct {
  16. *sql.DB
  17. once sync.Once
  18. }
  19. func getCachedSqlConn(driverName, server string) (*pingedDB, error) {
  20. val, err := connManager.GetResource(server, func() (io.Closer, error) {
  21. conn, err := newDBConnection(driverName, server)
  22. if err != nil {
  23. return nil, err
  24. }
  25. return &pingedDB{
  26. DB: conn,
  27. }, nil
  28. })
  29. if err != nil {
  30. return nil, err
  31. }
  32. return val.(*pingedDB), nil
  33. }
  34. func getSqlConn(driverName, server string) (*sql.DB, error) {
  35. pdb, err := getCachedSqlConn(driverName, server)
  36. if err != nil {
  37. return nil, err
  38. }
  39. pdb.once.Do(func() {
  40. err = pdb.Ping()
  41. })
  42. if err != nil {
  43. return nil, err
  44. }
  45. return pdb.DB, nil
  46. }
  47. func newDBConnection(driverName, datasource string) (*sql.DB, error) {
  48. conn, err := sql.Open(driverName, datasource)
  49. if err != nil {
  50. return nil, err
  51. }
  52. // we need to do this until the issue https://github.com/golang/go/issues/9851 get fixed
  53. // discussed here https://github.com/go-sql-driver/mysql/issues/257
  54. // if the discussed SetMaxIdleTimeout methods added, we'll change this behavior
  55. // 8 means we can't have more than 8 goroutines to concurrently access the same database.
  56. conn.SetMaxIdleConns(maxIdleConns)
  57. conn.SetMaxOpenConns(maxOpenConns)
  58. conn.SetConnMaxLifetime(maxLifetime)
  59. return conn, nil
  60. }