diff --git a/db.go b/db.go
index 918050cb703a0761b5cb9d686f8dd7f652a8f64f..a96a371634dbaaa6e38d0873d0058e13143fd2db 100644
--- a/db.go
+++ b/db.go
@@ -79,6 +79,7 @@ package db // import "upper.io/db.v2"
 import (
 	"fmt"
 	"reflect"
+	"time"
 )
 
 // Constraint interface represents a condition.
@@ -573,3 +574,9 @@ var (
 	_ Constraint  = &constraint{}
 	_ RawValue    = &rawValue{}
 )
+
+var (
+	DefaultConnMaxLifetime = time.Duration(0)
+	DefaultMaxIdleConns    = 0
+	DefaultMaxOpenConns    = 0
+)
diff --git a/internal/sqladapter/collection.go b/internal/sqladapter/collection.go
index c616cf4cb18a65fad29fb6f5d273fb70afa7fd56..14d4ac8a40fec7ad4d9b22bd0b0b0368284cf015 100644
--- a/internal/sqladapter/collection.go
+++ b/internal/sqladapter/collection.go
@@ -82,10 +82,10 @@ func (c *collection) InsertReturning(item interface{}) error {
 		// Not within a transaction, let's create one.
 		var err error
 		tx, err = c.p.Database().NewLocalTransaction()
-		defer tx.Close()
 		if err != nil {
 			return err
 		}
+		defer tx.Close()
 	}
 
 	var res db.Result
diff --git a/internal/sqladapter/testing/adapter.go.tpl b/internal/sqladapter/testing/adapter.go.tpl
index 6c68a922a48c0864977057ee0b9b689ad9b1d906..f9d1af5a6a5c2b21c725db87d33e60eb89e993df 100644
--- a/internal/sqladapter/testing/adapter.go.tpl
+++ b/internal/sqladapter/testing/adapter.go.tpl
@@ -830,8 +830,7 @@ func TestDelete(t *testing.T) {
 
 func TestCompositeKeys(t *testing.T) {
 	if Adapter == "ql" {
-		t.Logf("Unsupported, skipped")
-		return
+		t.Skip("Currently not supported.")
 	}
 
 	sess := mustOpen()
@@ -864,8 +863,7 @@ func TestCompositeKeys(t *testing.T) {
 // Attempts to test database transactions.
 func TestTransactionsAndRollback(t *testing.T) {
 	if Adapter == "ql" {
-		t.Logf("Skipped.")
-		return
+		t.Skip("Currently not supported.")
 	}
 
 	sess := mustOpen()
@@ -986,8 +984,7 @@ func TestTransactionsAndRollback(t *testing.T) {
 
 func TestDataTypes(t *testing.T) {
 	if Adapter == "ql" {
-		t.Logf("Skipped.")
-		return
+		t.Skip("Currently not supported.")
 	}
 
 	type testValuesStruct struct {
@@ -1124,11 +1121,11 @@ func TestBuilder(t *testing.T) {
 
 func TestExhaustConnectionPool(t *testing.T) {
 	if Adapter == "ql" {
-		t.Logf("Skipped.")
-		return
+		t.Skip("Currently not supported.")
 	}
 
 	var tMu sync.Mutex
+
 	tFatal := func(err error) {
 		tMu.Lock()
 		defer tMu.Unlock()
@@ -1154,6 +1151,7 @@ func TestExhaustConnectionPool(t *testing.T) {
 
 			// Requesting a new transaction session.
 			start := time.Now()
+			tLogf("Tx: %d: NewTx")
 			tx, err := sess.NewTx()
 			if err != nil {
 				tFatal(err)
diff --git a/mysql/database.go b/mysql/database.go
index 798aa4a9ef0391fb1d89d7653b93bb696c8da631..c660f14d199f693538678e6404558eb28a78ab95 100644
--- a/mysql/database.go
+++ b/mysql/database.go
@@ -112,6 +112,9 @@ func (d *database) open() error {
 	connFn := func() error {
 		sess, err := sql.Open("mysql", d.ConnectionURL().String())
 		if err == nil {
+			sess.SetConnMaxLifetime(connMaxLifetime)
+			sess.SetMaxIdleConns(maxIdleConns)
+			sess.SetMaxOpenConns(maxOpenConns)
 			return d.BaseDatabase.BindSession(sess)
 		}
 		return err
diff --git a/mysql/mysql.go b/mysql/mysql.go
index 56d42cf4676a0796efd8ae024700871b675af438..470db3747977cd7722ba193e4928fce20d6d3684 100644
--- a/mysql/mysql.go
+++ b/mysql/mysql.go
@@ -23,6 +23,7 @@ package mysql // import "upper.io/db.v2/mysql"
 
 import (
 	"database/sql"
+	"time"
 
 	"upper.io/db.v2"
 
@@ -30,6 +31,12 @@ import (
 	"upper.io/db.v2/lib/sqlbuilder"
 )
 
+var (
+	connMaxLifetime time.Duration = db.DefaultConnMaxLifetime
+	maxIdleConns    int           = db.DefaultMaxIdleConns
+	maxOpenConns    int           = db.DefaultMaxOpenConns
+)
+
 const sqlDriver = `mysql`
 
 // Adapter is the public name of the adapter.
@@ -102,3 +109,30 @@ func New(sess *sql.DB) (sqlbuilder.Database, error) {
 	}
 	return d, nil
 }
+
+// SetConnMaxLifetime sets the default value to be passed to
+// db.SetConnMaxLifetime.
+func SetConnMaxLifetime(d time.Duration) {
+	connMaxLifetime = d
+}
+
+// SetMaxIdleConns sets the default value to be passed to db.SetMaxOpenConns.
+func SetMaxIdleConns(n int) {
+	if n < 0 {
+		n = 0
+	}
+	maxIdleConns = n
+}
+
+// SetMaxOpenConns sets the default value to be passed to db.SetMaxOpenConns.
+// If the value of maxIdleConns is >= 0 and maxOpenConns is less than
+// maxIdleConns, then maxIdleConns will be reduced to match maxOpenConns.
+func SetMaxOpenConns(n int) {
+	if n < 0 {
+		n = 0
+	}
+	if n > maxIdleConns {
+		maxIdleConns = n
+	}
+	maxOpenConns = n
+}
diff --git a/postgresql/database.go b/postgresql/database.go
index 28a61791186ad832ff60fca261bf0a74f61cd440..0933942e6785d5ca0388c92d8ecd608fc5772181 100644
--- a/postgresql/database.go
+++ b/postgresql/database.go
@@ -111,6 +111,9 @@ func (d *database) open() error {
 	connFn := func() error {
 		sess, err := sql.Open("postgres", d.ConnectionURL().String())
 		if err == nil {
+			sess.SetConnMaxLifetime(connMaxLifetime)
+			sess.SetMaxIdleConns(maxIdleConns)
+			sess.SetMaxOpenConns(maxOpenConns)
 			return d.BaseDatabase.BindSession(sess)
 		}
 		return err
diff --git a/postgresql/postgresql.go b/postgresql/postgresql.go
index 9612e6aa672eed1210545223e31d886536c93a66..0572350a498207aec552e493fc6921dec68ff4a7 100644
--- a/postgresql/postgresql.go
+++ b/postgresql/postgresql.go
@@ -23,6 +23,7 @@ package postgresql // import "upper.io/db.v2/postgresql"
 
 import (
 	"database/sql"
+	"time"
 
 	"upper.io/db.v2"
 
@@ -30,6 +31,12 @@ import (
 	"upper.io/db.v2/lib/sqlbuilder"
 )
 
+var (
+	connMaxLifetime time.Duration = db.DefaultConnMaxLifetime
+	maxIdleConns    int           = db.DefaultMaxIdleConns
+	maxOpenConns    int           = db.DefaultMaxOpenConns
+)
+
 const sqlDriver = `postgres`
 
 // Adapter is the public name of the adapter.
@@ -102,3 +109,30 @@ func New(sess *sql.DB) (sqlbuilder.Database, error) {
 	}
 	return d, nil
 }
+
+// SetConnMaxLifetime sets the default value to be passed to
+// db.SetConnMaxLifetime.
+func SetConnMaxLifetime(d time.Duration) {
+	connMaxLifetime = d
+}
+
+// SetMaxIdleConns sets the default value to be passed to db.SetMaxOpenConns.
+func SetMaxIdleConns(n int) {
+	if n < 0 {
+		n = 0
+	}
+	maxIdleConns = n
+}
+
+// SetMaxOpenConns sets the default value to be passed to db.SetMaxOpenConns.
+// If the value of maxIdleConns is >= 0 and maxOpenConns is less than
+// maxIdleConns, then maxIdleConns will be reduced to match maxOpenConns.
+func SetMaxOpenConns(n int) {
+	if n < 0 {
+		n = 0
+	}
+	if n > maxIdleConns {
+		maxIdleConns = n
+	}
+	maxOpenConns = n
+}