go-goracle / goracle

Go database/sql driver for connecting to Oracle Database, using the ODPI-C library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Connection configuration

wthongkham2 opened this issue · comments

I was wondering if there was a standard way of setting up the database configuration here is mine for reference.

func (c *DatabaseConfig) openConnection() (*sql.DB, bool, error) {
	startTime := time.Now()
	conn := goracle.ConnectionParams{
		Username:             c.User,
		Password:             c.Password,
		SID:                  fmt.Sprintf("%s/%s:%s", c.Host, c.DatabaseName, "POOLED"),
		ConnClass:            "POOLED",
		MinSessions:          4,
		MaxSessions:          200,
		PoolIncrement:        2,
		StandaloneConnection: false,
		EnableEvents:         false,
		HeterogeneousPool:    false,
		IsPrelim:             false,
		// WaitTimeout:          60000,
		// MaxLifeTime:          86400,
		// SessionTimeout:       360,
	}
	db, err := sql.Open("goracle", conn.StringWithPassword())
	if err != nil {
		log.Error(err.Error())
		return nil, false, err
	}
	db.SetMaxOpenConns(50)
	db.SetMaxIdleConns(50)
	db.SetConnMaxLifetime(time.Minute * 1)
	log.Errorf("connection obtained in %s", time.Now().Sub(startTime).String())
	return db, false, nil
}

Whenever i tried to run this it would work until the connection becomes inactive and it seemed like it could not make a connection again. I also tried adding a function that would ping the database to just keep the connection open, this worked but it seemed to keep alot of connections idle for a long time on the database. I was wondering if there are suggestions on how to set up the connection. Also I have the sql.DB acting as a singleton, do you see any problems with passing that that around for each transaction?

db.SetMaxIdleConns means at least 50 connections will be kept idle in the Go db pool, even when they're not in use. And that's only the Go's pool.

Oracle's pool (goracle uses a session pool, and you configure it with ConnectionParams) is another layer.

When the Go's pool decides a connection is not to be used anymore (over 50 in your case), it calls the driver's Close on it - and it willjust return the connection to Oracle's session pool.

So with MaxSessions=200, you allow 200 sessions - though you only allow 50 on the Go side.
I would make MaxSessions = MaxOpenConns.

"Whenever i tried to run this it would work until the connection becomes inactive and it seemed like it could not make a connection again"
Are you sure you Close all Rows, Stmt, Tx in time? Use Context and cancel it at boundaries!
Spawn a goroutine and log db.Stats() regularly.

"Also I have the sql.DB acting as a singleton"
That's ok.

Thank you so much for your insight. I really appreciate your detailed answer.