You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by da...@apache.org on 2018/07/04 02:39:28 UTC

[trafficcontrol] 03/15: converted all packages to use db-less interfaces

This is an automated email from the ASF dual-hosted git repository.

dangogh pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git

commit 084310b24bff938bf2d8c0b8602adbe45ddd8186
Author: Dylan Volz <Dy...@comcast.com>
AuthorDate: Tue Jun 26 17:08:29 2018 -0600

    converted all packages to use db-less interfaces
---
 .../traffic_ops_golang/api/shared_handlers.go      |  46 +++++++
 .../deliveryservice/deliveryservicesv12.go         |   4 +-
 .../deliveryservice/deliveryservicesv13.go         |   4 +-
 .../deliveryservice/servers/servers.go             |  18 ++-
 .../traffic_ops_golang/parameter/parameters.go     | 146 ++++++---------------
 .../parameter/parameters_test.go                   |   9 +-
 .../physlocation/phys_locations.go                 | 100 +++-----------
 .../physlocation/phys_locations_test.go            |  10 +-
 traffic_ops/traffic_ops_golang/profile/profiles.go | 108 ++++-----------
 .../traffic_ops_golang/profile/profiles_test.go    |  10 +-
 .../profileparameter/profile_parameters.go         |  79 +++--------
 .../profileparameter/profile_parameters_test.go    |   9 +-
 traffic_ops/traffic_ops_golang/region/regions.go   | 102 +++-----------
 .../traffic_ops_golang/region/regions_test.go      |  10 +-
 traffic_ops/traffic_ops_golang/role/roles.go       | 119 ++++-------------
 traffic_ops/traffic_ops_golang/role/roles_test.go  |   9 +-
 traffic_ops/traffic_ops_golang/routes.go           | 120 ++++++++---------
 traffic_ops/traffic_ops_golang/server/servers.go   | 114 ++++------------
 .../traffic_ops_golang/server/servers_test.go      |   3 +-
 .../staticdnsentry/staticdnsentry.go               |  19 ++-
 traffic_ops/traffic_ops_golang/status/statuses.go  | 103 +++------------
 .../traffic_ops_golang/status/statuses_test.go     |  10 +-
 traffic_ops/traffic_ops_golang/types/types.go      | 102 +++-----------
 traffic_ops/traffic_ops_golang/types/types_test.go |  11 +-
 24 files changed, 407 insertions(+), 858 deletions(-)

diff --git a/traffic_ops/traffic_ops_golang/api/shared_handlers.go b/traffic_ops/traffic_ops_golang/api/shared_handlers.go
index b01eb85..4a10cdb 100644
--- a/traffic_ops/traffic_ops_golang/api/shared_handlers.go
+++ b/traffic_ops/traffic_ops_golang/api/shared_handlers.go
@@ -162,6 +162,52 @@ func ReadHandler(typeFactory func(reqInfo *APIInfo) CRUDer) http.HandlerFunc {
 	}
 }
 
+//this creates a handler function from the pointer to a struct implementing the Reader interface
+//      this handler retrieves the user from the context
+//      combines the path and query parameters
+//      produces the proper status code based on the error code returned
+//      marshals the structs returned into the proper response json
+func ReadOnlyHandler(typeFactory func(reqInfo *APIInfo) Reader) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		//create error function with ResponseWriter and Request
+		handleErrs := tc.GetHandleErrorsFunc(w, r)
+
+		inf, userErr, sysErr, errCode := NewInfo(r, nil, nil)
+		if userErr != nil || sysErr != nil {
+			HandleErr(w, r, errCode, userErr, sysErr)
+			return
+		}
+		defer inf.Close()
+
+		// Load the PathParams into the query parameters for pass through
+		params, err := GetCombinedParams(r)
+		if err != nil {
+			log.Errorf("unable to get parameters from request: %s", err)
+			handleErrs(http.StatusInternalServerError, err)
+		}
+
+		reader := typeFactory(inf)
+
+		results, errs, errType := reader.Read(params)
+		if len(errs) > 0 {
+			tc.HandleErrorsWithType(errs, errType, handleErrs)
+			return
+		}
+		resp := struct {
+			Response []interface{} `json:"response"`
+		}{results}
+
+		respBts, err := json.Marshal(resp)
+		if err != nil {
+			handleErrs(http.StatusInternalServerError, err)
+			return
+		}
+
+		w.Header().Set("Content-Type", "application/json")
+		fmt.Fprintf(w, "%s", respBts)
+	}
+}
+
 //this creates a handler function from the pointer to a struct implementing the Updater interface
 //it must be immediately assigned to a local variable
 //   this generic handler encapsulates the logic for handling:
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv12.go b/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv12.go
index a783a90..aa0d36a 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv12.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv12.go
@@ -126,8 +126,8 @@ func GetXMLID(tx *sql.Tx, id int) (string, bool, error) {
 
 // IsTenantAuthorized checks that the user is authorized for both the delivery service's existing tenant, and the new tenant they're changing it to (if different).
 
-func (ds *TODeliveryServiceV12) IsTenantAuthorized(user *auth.CurrentUser, tx *sqlx.Tx) (bool, error) {
-	return isTenantAuthorized(user, tx, &ds.DeliveryServiceNullableV12)
+func (ds *TODeliveryServiceV12) IsTenantAuthorized(user *auth.CurrentUser) (bool, error) {
+	return isTenantAuthorized(user, ds.ReqInfo.Tx, &ds.DeliveryServiceNullableV12)
 }
 
 
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv13.go b/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv13.go
index 994d498..23d9d01 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv13.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/deliveryservicesv13.go
@@ -579,8 +579,8 @@ func (ds *TODeliveryServiceV13) Delete() (error, tc.ApiErrorType) {
 }
 
 // IsTenantAuthorized implements the Tenantable interface to ensure the user is authorized on the deliveryservice tenant
-func (ds *TODeliveryServiceV13) IsTenantAuthorized(user *auth.CurrentUser, tx *sqlx.Tx) (bool, error) {
-	return ds.V12().IsTenantAuthorized(user, tx)
+func (ds *TODeliveryServiceV13) IsTenantAuthorized(user *auth.CurrentUser) (bool, error) {
+	return ds.V12().IsTenantAuthorized(user)
 }
 
 func filterAuthorized(dses []tc.DeliveryServiceNullableV13, user *auth.CurrentUser, db *sqlx.DB) ([]tc.DeliveryServiceNullableV13, error) {
diff --git a/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go b/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
index a497946..48406af 100644
--- a/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
+++ b/traffic_ops/traffic_ops_golang/deliveryservice/servers/servers.go
@@ -713,16 +713,20 @@ func dssSelectQuery() string {
 	return selectStmt
 }
 
-type TODSSDeliveryService tc.DSSDeliveryService
-
-var dserviceRef = TODSSDeliveryService(tc.DSSDeliveryService{})
+type TODSSDeliveryService struct{
+	ReqInfo *api.APIInfo `json:"-"`
+	tc.DSSDeliveryService
+}
 
-func GetDServiceRef() *TODSSDeliveryService {
-	return &dserviceRef
+func GetDSSDeliveryServiceReaderSingleton() func(reqInfo *api.APIInfo)api.Reader {
+	return func(reqInfo *api.APIInfo)api.Reader {
+		toReturn := TODSSDeliveryService{reqInfo, tc.DSSDeliveryService{}}
+		return &toReturn
+	}
 }
 
 // Read shows all of the delivery services associated with the specified server.
-func (dss *TODSSDeliveryService) Read(db *sqlx.DB, params map[string]string, user auth.CurrentUser) ([]interface{}, []error, tc.ApiErrorType) {
+func (dss *TODSSDeliveryService) Read(params map[string]string) ([]interface{}, []error, tc.ApiErrorType) {
 	var err error = nil
 	orderby := params["orderby"]
 	serverId := params["id"]
@@ -734,7 +738,7 @@ func (dss *TODSSDeliveryService) Read(db *sqlx.DB, params map[string]string, use
 	query := SDSSelectQuery()
 	log.Debugln("Query is ", query)
 
-	rows, err := db.Queryx(query, serverId)
+	rows, err := dss.ReqInfo.Tx.Queryx(query, serverId)
 	if err != nil {
 		log.Errorf("Error querying DeliveryserviceServers: %v", err)
 		return nil, []error{tc.DBError}, tc.SystemError
diff --git a/traffic_ops/traffic_ops_golang/parameter/parameters.go b/traffic_ops/traffic_ops_golang/parameter/parameters.go
index 87057e5..a948c01 100644
--- a/traffic_ops/traffic_ops_golang/parameter/parameters.go
+++ b/traffic_ops/traffic_ops_golang/parameter/parameters.go
@@ -49,57 +49,59 @@ var (
 )
 
 //we need a type alias to define functions on
-type TOParameter tc.ParameterNullable
-
-//the refType is passed into the handlers where a copy of its type is used to decode the json.
-var refType = TOParameter(tc.ParameterNullable{})
+type TOParameter struct{
+	ReqInfo *api.APIInfo `json:"-"`
+	tc.ParameterNullable
+}
 
-func GetRefType() *TOParameter {
-	return &refType
+func GetTypeSingleton() func(reqInfo *api.APIInfo)api.CRUDer {
+	return func(reqInfo *api.APIInfo)api.CRUDer {
+		toReturn := TOParameter{reqInfo, tc.ParameterNullable{}}
+		return &toReturn
+	}
 }
 
-func (parameter TOParameter) GetKeyFieldsInfo() []api.KeyFieldInfo {
+func (param TOParameter) GetKeyFieldsInfo() []api.KeyFieldInfo {
 	return []api.KeyFieldInfo{{IDQueryParam, api.GetIntKey}}
 }
 
 //Implementation of the Identifier, Validator interface functions
-func (parameter TOParameter) GetKeys() (map[string]interface{}, bool) {
-	if parameter.ID == nil {
+func (param TOParameter) GetKeys() (map[string]interface{}, bool) {
+	if param.ID == nil {
 		return map[string]interface{}{IDQueryParam: 0}, false
 	}
-	return map[string]interface{}{IDQueryParam: *parameter.ID}, true
+	return map[string]interface{}{IDQueryParam: *param.ID}, true
 }
 
-func (parameter *TOParameter) SetKeys(keys map[string]interface{}) {
+func (param *TOParameter) SetKeys(keys map[string]interface{}) {
 	i, _ := keys[IDQueryParam].(int) //this utilizes the non panicking type assertion, if the thrown away ok variable is false i will be the zero of the type, 0 here.
-	parameter.ID = &i
+	param.ID = &i
 }
 
-func (parameter *TOParameter) GetAuditName() string {
-	if parameter.Name != nil {
-		return *parameter.Name
+func (param *TOParameter) GetAuditName() string {
+	if param.Name != nil {
+		return *param.Name
 	}
-	if parameter.ID != nil {
-		return strconv.Itoa(*parameter.ID)
+	if param.ID != nil {
+		return strconv.Itoa(*param.ID)
 	}
 	return "unknown"
 }
 
-func (parameter *TOParameter) GetType() string {
-	return "parameter"
+func (param *TOParameter) GetType() string {
+	return "param"
 }
 
 // Validate fulfills the api.Validator interface
-func (parameter TOParameter) Validate(db *sqlx.DB) []error {
-
+func (param TOParameter) Validate() []error {
 	// Test
 	// - Secure Flag is always set to either 1/0
 	// - Admin rights only
 	// - Do not allow duplicate parameters by name+config_file+value
 	errs := validation.Errors{
-		NameQueryParam:       validation.Validate(parameter.Name, validation.Required),
-		ConfigFileQueryParam: validation.Validate(parameter.ConfigFile, validation.Required),
-		ValueQueryParam:      validation.Validate(parameter.Value, validation.Required),
+		NameQueryParam:       validation.Validate(param.Name, validation.Required),
+		ConfigFileQueryParam: validation.Validate(param.ConfigFile, validation.Required),
+		ValueQueryParam:      validation.Validate(param.Value, validation.Required),
 	}
 
 	return tovalidate.ToErrors(errs)
@@ -112,24 +114,8 @@ func (parameter TOParameter) Validate(db *sqlx.DB) []error {
 //generic error message returned
 //The insert sql returns the id and lastUpdated values of the newly inserted parameter and have
 //to be added to the struct
-func (pl *TOParameter) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
-	rollbackTransaction := true
-	tx, err := db.Beginx()
-	defer func() {
-		if tx == nil || !rollbackTransaction {
-			return
-		}
-		err := tx.Rollback()
-		if err != nil {
-			log.Errorln(errors.New("rolling back transaction: " + err.Error()))
-		}
-	}()
-
-	if err != nil {
-		log.Error.Printf("could not begin transaction: %v", err)
-		return tc.DBError, tc.SystemError
-	}
-	resultRows, err := tx.NamedQuery(insertQuery(), pl)
+func (param *TOParameter) Create() (error, tc.ApiErrorType) {
+	resultRows, err := param.ReqInfo.Tx.NamedQuery(insertQuery(), param)
 	if err != nil {
 		if pqErr, ok := err.(*pq.Error); ok {
 			err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
@@ -164,14 +150,9 @@ func (pl *TOParameter) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.Api
 		return tc.DBError, tc.SystemError
 	}
 
-	pl.SetKeys(map[string]interface{}{IDQueryParam: id})
-	pl.LastUpdated = &lastUpdated
-	err = tx.Commit()
-	if err != nil {
-		log.Errorln("Could not commit transaction: ", err)
-		return tc.DBError, tc.SystemError
-	}
-	rollbackTransaction = false
+	param.SetKeys(map[string]interface{}{IDQueryParam: id})
+	param.LastUpdated = &lastUpdated
+
 	return nil, tc.NoError
 }
 
@@ -188,10 +169,10 @@ secure) VALUES (
 	return query
 }
 
-func (parameter *TOParameter) Read(db *sqlx.DB, parameters map[string]string, user auth.CurrentUser) ([]interface{}, []error, tc.ApiErrorType) {
+func (param *TOParameter) Read(parameters map[string]string) ([]interface{}, []error, tc.ApiErrorType) {
 	var rows *sqlx.Rows
 
-	privLevel := user.PrivLevel
+	privLevel := param.ReqInfo.User.PrivLevel
 
 	// Query Parameters to Database Query column mappings
 	// see the fields mapped in the SQL query
@@ -210,7 +191,7 @@ func (parameter *TOParameter) Read(db *sqlx.DB, parameters map[string]string, us
 	query := selectQuery() + where + ParametersGroupBy() + orderBy
 	log.Debugln("Query is ", query)
 
-	rows, err := db.NamedQuery(query, queryValues)
+	rows, err := param.ReqInfo.Tx.NamedQuery(query, queryValues)
 	if err != nil {
 		log.Errorf("Error querying Parameters: %v", err)
 		return nil, []error{tc.DBError}, tc.SystemError
@@ -244,25 +225,9 @@ func (parameter *TOParameter) Read(db *sqlx.DB, parameters map[string]string, us
 //ParsePQUniqueConstraintError is used to determine if a parameter with conflicting values exists
 //if so, it will return an errorType of DataConflict and the type should be appended to the
 //generic error message returned
-func (pl *TOParameter) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
-	rollbackTransaction := true
-	tx, err := db.Beginx()
-	defer func() {
-		if tx == nil || !rollbackTransaction {
-			return
-		}
-		err := tx.Rollback()
-		if err != nil {
-			log.Errorln(errors.New("rolling back transaction: " + err.Error()))
-		}
-	}()
-
-	if err != nil {
-		log.Error.Printf("could not begin transaction: %v", err)
-		return tc.DBError, tc.SystemError
-	}
-	log.Debugf("about to run exec query: %s with parameter: %++v", updateQuery(), pl)
-	resultRows, err := tx.NamedQuery(updateQuery(), pl)
+func (param *TOParameter) Update() (error, tc.ApiErrorType) {
+	log.Debugf("about to run exec query: %s with parameter: %++v", updateQuery(), param)
+	resultRows, err := param.ReqInfo.Tx.NamedQuery(updateQuery(), param)
 	if err != nil {
 		if pqErr, ok := err.(*pq.Error); ok {
 			err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
@@ -287,43 +252,22 @@ func (pl *TOParameter) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.Api
 		}
 	}
 	log.Debugf("lastUpdated: %++v", lastUpdated)
-	pl.LastUpdated = &lastUpdated
+	param.LastUpdated = &lastUpdated
 	if rowsAffected != 1 {
 		if rowsAffected < 1 {
 			return errors.New("no parameter found with this id"), tc.DataMissingError
 		}
 		return fmt.Errorf("this update affected too many rows: %d", rowsAffected), tc.SystemError
 	}
-	err = tx.Commit()
-	if err != nil {
-		log.Errorln("Could not commit transaction: ", err)
-		return tc.DBError, tc.SystemError
-	}
-	rollbackTransaction = false
+
 	return nil, tc.NoError
 }
 
 //The Parameter implementation of the Deleter interface
 //all implementations of Deleter should use transactions and return the proper errorType
-func (pl *TOParameter) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
-	rollbackTransaction := true
-	tx, err := db.Beginx()
-	defer func() {
-		if tx == nil || !rollbackTransaction {
-			return
-		}
-		err := tx.Rollback()
-		if err != nil {
-			log.Errorln(errors.New("rolling back transaction: " + err.Error()))
-		}
-	}()
-
-	if err != nil {
-		log.Error.Printf("could not begin transaction: %v", err)
-		return tc.DBError, tc.SystemError
-	}
-	log.Debugf("about to run exec query: %s with parameter: %++v", deleteQuery(), pl)
-	result, err := tx.NamedExec(deleteQuery(), pl)
+func (param *TOParameter) Delete() (error, tc.ApiErrorType) {
+	log.Debugf("about to run exec query: %s with parameter: %++v", deleteQuery(), param)
+	result, err := param.ReqInfo.Tx.NamedExec(deleteQuery(), param)
 	if err != nil {
 		log.Errorf("received error: %++v from delete execution", err)
 		return tc.DBError, tc.SystemError
@@ -339,12 +283,6 @@ func (pl *TOParameter) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.Api
 		return fmt.Errorf("this create affected too many rows: %d", rowsAffected), tc.SystemError
 	}
 
-	err = tx.Commit()
-	if err != nil {
-		log.Errorln("Could not commit transaction: ", err)
-		return tc.DBError, tc.SystemError
-	}
-	rollbackTransaction = false
 	return nil, tc.NoError
 }
 
diff --git a/traffic_ops/traffic_ops_golang/parameter/parameters_test.go b/traffic_ops/traffic_ops_golang/parameter/parameters_test.go
index c638af3..9b465f9 100644
--- a/traffic_ops/traffic_ops_golang/parameter/parameters_test.go
+++ b/traffic_ops/traffic_ops_golang/parameter/parameters_test.go
@@ -24,14 +24,15 @@ import (
 	"time"
 
 	"github.com/apache/trafficcontrol/lib/go-tc"
+	"github.com/apache/trafficcontrol/lib/go-util"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
-	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/auth"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/test"
 	"github.com/jmoiron/sqlx"
 
 	"encoding/json"
 
 	sqlmock "gopkg.in/DATA-DOG/go-sqlmock.v1"
+	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/auth"
 )
 
 func getTestParameters() []tc.ParameterNullable {
@@ -90,10 +91,14 @@ func TestGetParameters(t *testing.T) {
 			ts.Value,
 		)
 	}
+	mock.ExpectBegin()
 	mock.ExpectQuery("SELECT").WillReturnRows(rows)
+	mock.ExpectCommit()
 	v := map[string]string{"name": "1"}
+	user := auth.CurrentUser{PrivLevel:30}
 
-	pps, errs, _ := refType.Read(db, v, auth.CurrentUser{})
+	reqInfo := api.APIInfo{Tx:db.MustBegin(),CommitTx:util.BoolPtr(false),User:&user}
+	pps, errs, _ := GetTypeSingleton()(&reqInfo).Read(v)
 	if len(errs) > 0 {
 		t.Errorf("parameter.Read expected: no errors, actual: %v", errs)
 	}
diff --git a/traffic_ops/traffic_ops_golang/physlocation/phys_locations.go b/traffic_ops/traffic_ops_golang/physlocation/phys_locations.go
index c204c9e..b579a99 100644
--- a/traffic_ops/traffic_ops_golang/physlocation/phys_locations.go
+++ b/traffic_ops/traffic_ops_golang/physlocation/phys_locations.go
@@ -28,7 +28,6 @@ import (
 	"github.com/apache/trafficcontrol/lib/go-tc"
 	"github.com/apache/trafficcontrol/lib/go-tc/tovalidate"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
-	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/auth"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/dbhelpers"
 
 	validation "github.com/go-ozzo/ozzo-validation"
@@ -37,13 +36,16 @@ import (
 )
 
 //we need a type alias to define functions on
-type TOPhysLocation tc.PhysLocationNullable
-
-//the refType is passed into the handlers where a copy of its type is used to decode the json.
-var refType = TOPhysLocation(tc.PhysLocationNullable{})
+type TOPhysLocation struct{
+	ReqInfo *api.APIInfo `json:"-"`
+	tc.PhysLocationNullable
+}
 
-func GetRefType() *TOPhysLocation {
-	return &refType
+func GetTypeSingleton() func(reqInfo *api.APIInfo)api.CRUDer {
+	return func(reqInfo *api.APIInfo)api.CRUDer {
+		toReturn := TOPhysLocation{reqInfo, tc.PhysLocationNullable{}}
+		return &toReturn
+	}
 }
 
 func (pl TOPhysLocation) GetKeyFieldsInfo() []api.KeyFieldInfo {
@@ -77,7 +79,7 @@ func (pl *TOPhysLocation) GetType() string {
 	return "physLocation"
 }
 
-func (pl *TOPhysLocation) Validate(db *sqlx.DB) []error {
+func (pl *TOPhysLocation) Validate() []error {
 	errs := validation.Errors{
 		"address":   validation.Validate(pl.Address, validation.Required),
 		"city":      validation.Validate(pl.City, validation.Required),
@@ -93,7 +95,7 @@ func (pl *TOPhysLocation) Validate(db *sqlx.DB) []error {
 	return nil
 }
 
-func (pl *TOPhysLocation) Read(db *sqlx.DB, parameters map[string]string, user auth.CurrentUser) ([]interface{}, []error, tc.ApiErrorType) {
+func (pl *TOPhysLocation) Read(parameters map[string]string) ([]interface{}, []error, tc.ApiErrorType) {
 	var rows *sqlx.Rows
 
 	// Query Parameters to Database Query column mappings
@@ -111,7 +113,7 @@ func (pl *TOPhysLocation) Read(db *sqlx.DB, parameters map[string]string, user a
 	query := selectQuery() + where + orderBy
 	log.Debugln("Query is ", query)
 
-	rows, err := db.NamedQuery(query, queryValues)
+	rows, err := pl.ReqInfo.Tx.NamedQuery(query, queryValues)
 	if err != nil {
 		log.Errorf("Error querying PhysLocations: %v", err)
 		return nil, []error{tc.DBError}, tc.SystemError
@@ -160,25 +162,9 @@ JOIN region r ON pl.region = r.id`
 //ParsePQUniqueConstraintError is used to determine if a phys_location with conflicting values exists
 //if so, it will return an errorType of DataConflict and the type should be appended to the
 //generic error message returned
-func (pl *TOPhysLocation) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
-	rollbackTransaction := true
-	tx, err := db.Beginx()
-	defer func() {
-		if tx == nil || !rollbackTransaction {
-			return
-		}
-		err := tx.Rollback()
-		if err != nil {
-			log.Errorln(errors.New("rolling back transaction: " + err.Error()))
-		}
-	}()
-
-	if err != nil {
-		log.Error.Printf("could not begin transaction: %v", err)
-		return tc.DBError, tc.SystemError
-	}
+func (pl *TOPhysLocation) Update() (error, tc.ApiErrorType) {
 	log.Debugf("about to run exec query: %s with phys_location: %++v", updateQuery(), pl)
-	resultRows, err := tx.NamedQuery(updateQuery(), pl)
+	resultRows, err := pl.ReqInfo.Tx.NamedQuery(updateQuery(), pl)
 	if err != nil {
 		if pqErr, ok := err.(*pq.Error); ok {
 			err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
@@ -210,12 +196,6 @@ func (pl *TOPhysLocation) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.
 		}
 		return fmt.Errorf("this update affected too many rows: %d", rowsAffected), tc.SystemError
 	}
-	err = tx.Commit()
-	if err != nil {
-		log.Errorln("Could not commit transaction: ", err)
-		return tc.DBError, tc.SystemError
-	}
-	rollbackTransaction = false
 	return nil, tc.NoError
 }
 
@@ -226,24 +206,8 @@ func (pl *TOPhysLocation) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.
 //generic error message returned
 //The insert sql returns the id and lastUpdated values of the newly inserted phys_location and have
 //to be added to the struct
-func (pl *TOPhysLocation) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
-	rollbackTransaction := true
-	tx, err := db.Beginx()
-	defer func() {
-		if tx == nil || !rollbackTransaction {
-			return
-		}
-		err := tx.Rollback()
-		if err != nil {
-			log.Errorln(errors.New("rolling back transaction: " + err.Error()))
-		}
-	}()
-
-	if err != nil {
-		log.Error.Printf("could not begin transaction: %v", err)
-		return tc.DBError, tc.SystemError
-	}
-	resultRows, err := tx.NamedQuery(insertQuery(), pl)
+func (pl *TOPhysLocation) Create() (error, tc.ApiErrorType) {
+	resultRows, err := pl.ReqInfo.Tx.NamedQuery(insertQuery(), pl)
 	if err != nil {
 		if pqErr, ok := err.(*pq.Error); ok {
 			err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
@@ -280,36 +244,16 @@ func (pl *TOPhysLocation) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.
 
 	pl.SetKeys(map[string]interface{}{"id": id})
 	pl.LastUpdated = &lastUpdated
-	err = tx.Commit()
-	if err != nil {
-		log.Errorln("Could not commit transaction: ", err)
-		return tc.DBError, tc.SystemError
-	}
-	rollbackTransaction = false
+
 	return nil, tc.NoError
 }
 
 //The PhysLocation implementation of the Deleter interface
 //all implementations of Deleter should use transactions and return the proper errorType
-func (pl *TOPhysLocation) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
-	rollbackTransaction := true
-	tx, err := db.Beginx()
-	defer func() {
-		if tx == nil || !rollbackTransaction {
-			return
-		}
-		err := tx.Rollback()
-		if err != nil {
-			log.Errorln(errors.New("rolling back transaction: " + err.Error()))
-		}
-	}()
+func (pl *TOPhysLocation) Delete() (error, tc.ApiErrorType) {
 
-	if err != nil {
-		log.Error.Printf("could not begin transaction: %v", err)
-		return tc.DBError, tc.SystemError
-	}
 	log.Debugf("about to run exec query: %s with phys_location: %++v", deleteQuery(), pl)
-	result, err := tx.NamedExec(deleteQuery(), pl)
+	result, err := pl.ReqInfo.Tx.NamedExec(deleteQuery(), pl)
 	if err != nil {
 		log.Errorf("received error: %++v from delete execution", err)
 		return tc.DBError, tc.SystemError
@@ -325,12 +269,6 @@ func (pl *TOPhysLocation) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.
 		return fmt.Errorf("this create affected too many rows: %d", rowsAffected), tc.SystemError
 	}
 
-	err = tx.Commit()
-	if err != nil {
-		log.Errorln("Could not commit transaction: ", err)
-		return tc.DBError, tc.SystemError
-	}
-	rollbackTransaction = false
 	return nil, tc.NoError
 }
 
diff --git a/traffic_ops/traffic_ops_golang/physlocation/phys_locations_test.go b/traffic_ops/traffic_ops_golang/physlocation/phys_locations_test.go
index f9161f7..3cad4ec 100644
--- a/traffic_ops/traffic_ops_golang/physlocation/phys_locations_test.go
+++ b/traffic_ops/traffic_ops_golang/physlocation/phys_locations_test.go
@@ -26,8 +26,8 @@ import (
 	"time"
 
 	"github.com/apache/trafficcontrol/lib/go-tc"
+	"github.com/apache/trafficcontrol/lib/go-util"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
-	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/auth"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/test"
 	"github.com/jmoiron/sqlx"
 
@@ -92,10 +92,14 @@ func TestGetPhysLocations(t *testing.T) {
 			ts.Zip,
 		)
 	}
+	mock.ExpectBegin()
 	mock.ExpectQuery("SELECT").WillReturnRows(rows)
+	mock.ExpectCommit()
 	v := map[string]string{"dsId": "1"}
 
-	physLocations, errs, _ := refType.Read(db, v, auth.CurrentUser{})
+	reqInfo := api.APIInfo{Tx:db.MustBegin(),CommitTx:util.BoolPtr(false)}
+
+	physLocations, errs, _ := GetTypeSingleton()(&reqInfo).Read(v)
 	if len(errs) > 0 {
 		t.Errorf("physLocation.Read expected: no errors, actual: %v", errs)
 	}
@@ -129,7 +133,7 @@ func TestInterfaces(t *testing.T) {
 
 func TestValidate(t *testing.T) {
 	p := TOPhysLocation{}
-	errs := test.SortErrors(p.Validate(nil))
+	errs := test.SortErrors(p.Validate())
 	expected := test.SortErrors([]error{
 		errors.New("'state' cannot be blank"),
 		errors.New("'zip' cannot be blank"),
diff --git a/traffic_ops/traffic_ops_golang/profile/profiles.go b/traffic_ops/traffic_ops_golang/profile/profiles.go
index b7c6862..6b39006 100644
--- a/traffic_ops/traffic_ops_golang/profile/profiles.go
+++ b/traffic_ops/traffic_ops_golang/profile/profiles.go
@@ -47,14 +47,16 @@ const (
 )
 
 //we need a type alias to define functions on
-type TOProfile v13.ProfileNullable
-type TOParameter v13.ParameterNullable
-
-//the refType is passed into the handlers where a copy of its type is used to decode the json.
-var refType = TOProfile{}
+type TOProfile struct{
+	ReqInfo *api.APIInfo `json:"-"`
+	v13.ProfileNullable
+}
 
-func GetRefType() *TOProfile {
-	return &refType
+func GetTypeSingleton() func(reqInfo *api.APIInfo)api.CRUDer {
+	return func(reqInfo *api.APIInfo)api.CRUDer {
+		toReturn := TOProfile{reqInfo, v13.ProfileNullable{}}
+		return &toReturn
+	}
 }
 
 func (prof TOProfile) GetKeyFieldsInfo() []api.KeyFieldInfo {
@@ -88,7 +90,7 @@ func (prof *TOProfile) GetType() string {
 	return "profile"
 }
 
-func (prof *TOProfile) Validate(db *sqlx.DB) []error {
+func (prof *TOProfile) Validate() []error {
 	errs := validation.Errors{
 		NameQueryParam:        validation.Validate(prof.Name, validation.Required),
 		DescriptionQueryParam: validation.Validate(prof.Description, validation.Required),
@@ -101,7 +103,7 @@ func (prof *TOProfile) Validate(db *sqlx.DB) []error {
 	return nil
 }
 
-func (prof *TOProfile) Read(db *sqlx.DB, parameters map[string]string, user auth.CurrentUser) ([]interface{}, []error, tc.ApiErrorType) {
+func (prof *TOProfile) Read(parameters map[string]string) ([]interface{}, []error, tc.ApiErrorType) {
 	var rows *sqlx.Rows
 
 	// Query Parameters to Database Query column mappings
@@ -118,7 +120,7 @@ func (prof *TOProfile) Read(db *sqlx.DB, parameters map[string]string, user auth
 	query := selectProfilesQuery() + where + orderBy
 	log.Debugln("Query is ", query)
 
-	rows, err := db.NamedQuery(query, queryValues)
+	rows, err := prof.ReqInfo.Tx.NamedQuery(query, queryValues)
 	if err != nil {
 		log.Errorf("Error querying Profile: %v", err)
 		return nil, []error{tc.DBError}, tc.SystemError
@@ -135,7 +137,7 @@ func (prof *TOProfile) Read(db *sqlx.DB, parameters map[string]string, user auth
 
 		// Attach Parameters if the 'id' parameter is sent
 		if _, ok := parameters[IDQueryParam]; ok {
-			params, err := ReadParameters(db, parameters, user, p)
+			params, err := ReadParameters(prof.ReqInfo.Tx, parameters, prof.ReqInfo.User, p)
 			p.Parameters = params
 			if len(errs) > 0 {
 				log.Errorf("Error getting Parameters: %v", err)
@@ -166,7 +168,7 @@ LEFT JOIN cdn c ON prof.cdn = c.id`
 	return query
 }
 
-func ReadParameters(db *sqlx.DB, parameters map[string]string, user auth.CurrentUser, profile v13.ProfileNullable) ([]v13.ParameterNullable, []error) {
+func ReadParameters(tx *sqlx.Tx, parameters map[string]string, user *auth.CurrentUser, profile v13.ProfileNullable) ([]v13.ParameterNullable, []error) {
 
 	var rows *sqlx.Rows
 	privLevel := user.PrivLevel
@@ -174,7 +176,7 @@ func ReadParameters(db *sqlx.DB, parameters map[string]string, user auth.Current
 	queryValues["profile_id"] = *profile.ID
 
 	query := selectParametersQuery()
-	rows, err := db.NamedQuery(query, queryValues)
+	rows, err := tx.NamedQuery(query, queryValues)
 	if err != nil {
 		log.Errorf("Error querying Parameter: %v", err)
 		return nil, []error{tc.DBError}
@@ -221,25 +223,9 @@ WHERE pp.profile = :profile_id`
 //ParsePQUniqueConstraintError is used to determine if a profile with conflicting values exists
 //if so, it will return an errorType of DataConflict and the type should be appended to the
 //generic error message returned
-func (prof *TOProfile) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
-	rollbackTransaction := true
-	tx, err := db.Beginx()
-	defer func() {
-		if tx == nil || !rollbackTransaction {
-			return
-		}
-		err := tx.Rollback()
-		if err != nil {
-			log.Errorln(errors.New("rolling back transaction: " + err.Error()))
-		}
-	}()
-
-	if err != nil {
-		log.Error.Printf("could not begin transaction: %v", err)
-		return tc.DBError, tc.SystemError
-	}
+func (prof *TOProfile) Update() (error, tc.ApiErrorType) {
 	log.Debugf("about to run exec query: %s with profile: %++v", updateQuery(), prof)
-	resultRows, err := tx.NamedQuery(updateQuery(), prof)
+	resultRows, err := prof.ReqInfo.Tx.NamedQuery(updateQuery(), prof)
 	if err != nil {
 		if pqErr, ok := err.(*pq.Error); ok {
 			err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
@@ -270,12 +256,7 @@ func (prof *TOProfile) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.Api
 		}
 		return fmt.Errorf("this update affected too many rows: %d", rowsAffected), tc.SystemError
 	}
-	err = tx.Commit()
-	if err != nil {
-		log.Errorln("Could not commit transaction: ", err)
-		return tc.DBError, tc.SystemError
-	}
-	rollbackTransaction = false
+
 	return nil, tc.NoError
 }
 
@@ -286,24 +267,8 @@ func (prof *TOProfile) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.Api
 //generic error message returned
 //The insert sql returns the id and lastUpdated values of the newly inserted profile and have
 //to be added to the struct
-func (prof *TOProfile) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
-	rollbackTransaction := true
-	tx, err := db.Beginx()
-	defer func() {
-		if tx == nil || !rollbackTransaction {
-			return
-		}
-		err := tx.Rollback()
-		if err != nil {
-			log.Errorln(errors.New("rolling back transaction: " + err.Error()))
-		}
-	}()
-
-	if err != nil {
-		log.Error.Printf("could not begin transaction: %v", err)
-		return tc.DBError, tc.SystemError
-	}
-	resultRows, err := tx.NamedQuery(insertQuery(), prof)
+func (prof *TOProfile) Create() (error, tc.ApiErrorType) {
+	resultRows, err := prof.ReqInfo.Tx.NamedQuery(insertQuery(), prof)
 	if err != nil {
 		if pqErr, ok := err.(*pq.Error); ok {
 			err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
@@ -340,36 +305,15 @@ func (prof *TOProfile) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.Api
 
 	prof.SetKeys(map[string]interface{}{IDQueryParam: id})
 	prof.LastUpdated = &lastUpdated
-	err = tx.Commit()
-	if err != nil {
-		log.Errorln("Could not commit transaction: ", err)
-		return tc.DBError, tc.SystemError
-	}
-	rollbackTransaction = false
+
 	return nil, tc.NoError
 }
 
 //The Profile implementation of the Deleter interface
 //all implementations of Deleter should use transactions and return the proper errorType
-func (prof *TOProfile) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
-	rollbackTransaction := true
-	tx, err := db.Beginx()
-	defer func() {
-		if tx == nil || !rollbackTransaction {
-			return
-		}
-		err := tx.Rollback()
-		if err != nil {
-			log.Errorln(errors.New("rolling back transaction: " + err.Error()))
-		}
-	}()
-
-	if err != nil {
-		log.Error.Printf("could not begin transaction: %v", err)
-		return tc.DBError, tc.SystemError
-	}
+func (prof *TOProfile) Delete() (error, tc.ApiErrorType) {
 	log.Debugf("about to run exec query: %s with profile: %++v", deleteQuery(), prof)
-	result, err := tx.NamedExec(deleteQuery(), prof)
+	result, err := prof.ReqInfo.Tx.NamedExec(deleteQuery(), prof)
 	if err != nil {
 		log.Errorf("received error: %++v from delete execution", err)
 		return tc.DBError, tc.SystemError
@@ -385,12 +329,6 @@ func (prof *TOProfile) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.Api
 		return fmt.Errorf("this create affected too many rows: %d", rowsAffected), tc.SystemError
 	}
 
-	err = tx.Commit()
-	if err != nil {
-		log.Errorln("Could not commit transaction: ", err)
-		return tc.DBError, tc.SystemError
-	}
-	rollbackTransaction = false
 	return nil, tc.NoError
 }
 
diff --git a/traffic_ops/traffic_ops_golang/profile/profiles_test.go b/traffic_ops/traffic_ops_golang/profile/profiles_test.go
index bf2fe08..b00ea6c 100644
--- a/traffic_ops/traffic_ops_golang/profile/profiles_test.go
+++ b/traffic_ops/traffic_ops_golang/profile/profiles_test.go
@@ -26,8 +26,8 @@ import (
 	"time"
 
 	"github.com/apache/trafficcontrol/lib/go-tc"
+	"github.com/apache/trafficcontrol/lib/go-util"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
-	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/auth"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/test"
 	"github.com/jmoiron/sqlx"
 
@@ -93,10 +93,14 @@ func TestGetProfiles(t *testing.T) {
 			ts.Type,
 		)
 	}
+	mock.ExpectBegin()
 	mock.ExpectQuery("SELECT").WillReturnRows(rows)
+	mock.ExpectCommit()
 	v := map[string]string{"name": "1"}
 
-	profiles, errs, _ := refType.Read(db, v, auth.CurrentUser{})
+	reqInfo := api.APIInfo{Tx:db.MustBegin(),CommitTx:util.BoolPtr(false)}
+
+	profiles, errs, _ := GetTypeSingleton()(&reqInfo).Read(v)
 	if len(errs) > 0 {
 		t.Errorf("profile.Read expected: no errors, actual: %v", errs)
 	}
@@ -130,7 +134,7 @@ func TestInterfaces(t *testing.T) {
 
 func TestValidate(t *testing.T) {
 	p := TOProfile{}
-	errs := test.SortErrors(p.Validate(nil))
+	errs := test.SortErrors(p.Validate())
 	expected := test.SortErrors([]error{
 		errors.New("'cdn' cannot be blank"),
 		errors.New("'description' cannot be blank"),
diff --git a/traffic_ops/traffic_ops_golang/profileparameter/profile_parameters.go b/traffic_ops/traffic_ops_golang/profileparameter/profile_parameters.go
index 9920228..703d40c 100644
--- a/traffic_ops/traffic_ops_golang/profileparameter/profile_parameters.go
+++ b/traffic_ops/traffic_ops_golang/profileparameter/profile_parameters.go
@@ -29,7 +29,6 @@ import (
 	"github.com/apache/trafficcontrol/lib/go-tc/tovalidate"
 	"github.com/apache/trafficcontrol/lib/go-tc/v13"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
-	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/auth"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/dbhelpers"
 
 	validation "github.com/go-ozzo/ozzo-validation"
@@ -43,13 +42,16 @@ const (
 )
 
 //we need a type alias to define functions on
-type TOProfileParameter v13.ProfileParameterNullable
-
-//the refType is passed into the handlers where a copy of its type is used to decode the json.
-var refType = TOProfileParameter(v13.ProfileParameterNullable{})
+type TOProfileParameter struct{
+	ReqInfo *api.APIInfo `json:"-"`
+	v13.ProfileParameterNullable
+}
 
-func GetRefType() *TOProfileParameter {
-	return &refType
+func GetTypeSingleton() func(reqInfo *api.APIInfo)api.CRUDer {
+	return func(reqInfo *api.APIInfo)api.CRUDer {
+		toReturn := TOProfileParameter{reqInfo, v13.ProfileParameterNullable{}}
+		return &toReturn
+	}
 }
 
 func (pp TOProfileParameter) GetKeyFieldsInfo() []api.KeyFieldInfo {
@@ -93,7 +95,7 @@ func (pp *TOProfileParameter) SetKeys(keys map[string]interface{}) {
 }
 
 // Validate fulfills the api.Validator interface
-func (pp *TOProfileParameter) Validate(db *sqlx.DB) []error {
+func (pp *TOProfileParameter) Validate() []error {
 
 	errs := validation.Errors{
 		"profile":   validation.Validate(pp.ProfileID, validation.Required),
@@ -110,24 +112,8 @@ func (pp *TOProfileParameter) Validate(db *sqlx.DB) []error {
 //generic error message returned
 //The insert sql returns the profile and lastUpdated values of the newly inserted profileparameter and have
 //to be added to the struct
-func (pp *TOProfileParameter) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
-	rollbackTransaction := true
-	tx, err := db.Beginx()
-	defer func() {
-		if tx == nil || !rollbackTransaction {
-			return
-		}
-		err := tx.Rollback()
-		if err != nil {
-			log.Errorln(errors.New("rolling back transaction: " + err.Error()))
-		}
-	}()
-
-	if err != nil {
-		log.Error.Printf("could not begin transaction: %v", err)
-		return tc.DBError, tc.SystemError
-	}
-	resultRows, err := tx.NamedQuery(insertQuery(), pp)
+func (pp *TOProfileParameter) Create() (error, tc.ApiErrorType) {
+	resultRows, err := pp.ReqInfo.Tx.NamedQuery(insertQuery(), pp)
 	if err != nil {
 		if pqErr, ok := err.(*pq.Error); ok {
 			err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
@@ -164,13 +150,6 @@ func (pp *TOProfileParameter) Create(db *sqlx.DB, user auth.CurrentUser) (error,
 	}
 
 	pp.SetKeys(map[string]interface{}{ProfileIDQueryParam: profile, ParameterIDQueryParam: parameter})
-	pp.LastUpdated = &lastUpdated
-	err = tx.Commit()
-	if err != nil {
-		log.Errorln("Could not commit transaction: ", err)
-		return tc.DBError, tc.SystemError
-	}
-	rollbackTransaction = false
 	return nil, tc.NoError
 }
 
@@ -183,7 +162,11 @@ parameter) VALUES (
 	return query
 }
 
-func (pp *TOProfileParameter) Read(db *sqlx.DB, parameters map[string]string, user auth.CurrentUser) ([]interface{}, []error, tc.ApiErrorType) {
+func (pp *TOProfileParameter) Update() (error, tc.ApiErrorType) {
+	return errors.New("unimplemented"), tc.SystemError
+}
+
+func (pp *TOProfileParameter) Read(parameters map[string]string) ([]interface{}, []error, tc.ApiErrorType) {
 	var rows *sqlx.Rows
 
 	// Query Parameters to Database Query column mappings
@@ -202,7 +185,7 @@ func (pp *TOProfileParameter) Read(db *sqlx.DB, parameters map[string]string, us
 	query := selectQuery() + where + orderBy
 	log.Debugln("Query is ", query)
 
-	rows, err := db.NamedQuery(query, queryValues)
+	rows, err := pp.ReqInfo.Tx.NamedQuery(query, queryValues)
 	if err != nil {
 		log.Errorf("Error querying Parameters: %v", err)
 		return nil, []error{tc.DBError}, tc.SystemError
@@ -225,25 +208,9 @@ func (pp *TOProfileParameter) Read(db *sqlx.DB, parameters map[string]string, us
 
 //The Parameter implementation of the Deleter interface
 //all implementations of Deleter should use transactions and return the proper errorType
-func (pp *TOProfileParameter) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
-	rollbackTransaction := true
-	tx, err := db.Beginx()
-	defer func() {
-		if tx == nil || !rollbackTransaction {
-			return
-		}
-		err := tx.Rollback()
-		if err != nil {
-			log.Errorln(errors.New("rolling back transaction: " + err.Error()))
-		}
-	}()
-
-	if err != nil {
-		log.Error.Printf("could not begin transaction: %v", err)
-		return tc.DBError, tc.SystemError
-	}
+func (pp *TOProfileParameter) Delete() (error, tc.ApiErrorType) {
 	log.Debugf("about to run exec query: %s with parameter: %++v", deleteQuery(), pp)
-	result, err := tx.NamedExec(deleteQuery(), pp)
+	result, err := pp.ReqInfo.Tx.NamedExec(deleteQuery(), pp)
 	if err != nil {
 		log.Errorf("received error: %++v from delete execution", err)
 		return tc.DBError, tc.SystemError
@@ -259,12 +226,6 @@ func (pp *TOProfileParameter) Delete(db *sqlx.DB, user auth.CurrentUser) (error,
 		return fmt.Errorf("this create affected too many rows: %d", rowsAffected), tc.SystemError
 	}
 
-	err = tx.Commit()
-	if err != nil {
-		log.Errorln("Could not commit transaction: ", err)
-		return tc.DBError, tc.SystemError
-	}
-	rollbackTransaction = false
 	return nil, tc.NoError
 }
 
diff --git a/traffic_ops/traffic_ops_golang/profileparameter/profile_parameters_test.go b/traffic_ops/traffic_ops_golang/profileparameter/profile_parameters_test.go
index b11f64b..013ce3a 100644
--- a/traffic_ops/traffic_ops_golang/profileparameter/profile_parameters_test.go
+++ b/traffic_ops/traffic_ops_golang/profileparameter/profile_parameters_test.go
@@ -25,8 +25,8 @@ import (
 
 	"github.com/apache/trafficcontrol/lib/go-tc"
 	"github.com/apache/trafficcontrol/lib/go-tc/v13"
+	"github.com/apache/trafficcontrol/lib/go-util"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
-	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/auth"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/test"
 	"github.com/jmoiron/sqlx"
 
@@ -78,10 +78,15 @@ func TestGetProfileParameters(t *testing.T) {
 			ts.ParameterID,
 		)
 	}
+	mock.ExpectBegin()
 	mock.ExpectQuery("SELECT").WillReturnRows(rows)
+	mock.ExpectCommit()
 	v := map[string]string{"profile": "1"}
 
-	pps, errs, _ := refType.Read(db, v, auth.CurrentUser{})
+	reqInfo := api.APIInfo{Tx:db.MustBegin(),CommitTx:util.BoolPtr(false)}
+
+
+	pps, errs, _ := GetTypeSingleton()(&reqInfo).Read(v)
 	if len(errs) > 0 {
 		t.Errorf("profileparameter.Read expected: no errors, actual: %v", errs)
 	}
diff --git a/traffic_ops/traffic_ops_golang/region/regions.go b/traffic_ops/traffic_ops_golang/region/regions.go
index 730870a..b54598c 100644
--- a/traffic_ops/traffic_ops_golang/region/regions.go
+++ b/traffic_ops/traffic_ops_golang/region/regions.go
@@ -26,20 +26,22 @@ import (
 	"github.com/apache/trafficcontrol/lib/go-log"
 	"github.com/apache/trafficcontrol/lib/go-tc"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
-	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/auth"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/dbhelpers"
 	"github.com/jmoiron/sqlx"
 	"github.com/lib/pq"
 )
 
 //we need a type alias to define functions on
-type TORegion tc.Region
-
-//the refType is passed into the handlers where a copy of its type is used to decode the json.
-var refType = TORegion(tc.Region{})
+type TORegion struct{
+	ReqInfo *api.APIInfo `json:"-"`
+	tc.Region
+}
 
-func GetRefType() *TORegion {
-	return &refType
+func GetTypeSingleton() func(reqInfo *api.APIInfo)api.CRUDer {
+	return func(reqInfo *api.APIInfo)api.CRUDer {
+		toReturn := TORegion{reqInfo, tc.Region{}}
+		return &toReturn
+	}
 }
 
 func (region TORegion) GetKeyFieldsInfo() []api.KeyFieldInfo {
@@ -64,7 +66,7 @@ func (region *TORegion) GetType() string {
 	return "region"
 }
 
-func (region *TORegion) Validate(db *sqlx.DB) []error {
+func (region *TORegion) Validate() []error {
 	errs := []error{}
 	if len(region.Name) < 1 {
 		errs = append(errs, errors.New(`Region 'name' is required.`))
@@ -72,7 +74,7 @@ func (region *TORegion) Validate(db *sqlx.DB) []error {
 	return errs
 }
 
-func (region *TORegion) Read(db *sqlx.DB, parameters map[string]string, user auth.CurrentUser) ([]interface{}, []error, tc.ApiErrorType) {
+func (region *TORegion) Read(parameters map[string]string) ([]interface{}, []error, tc.ApiErrorType) {
 	var rows *sqlx.Rows
 
 	// Query Parameters to Database Query column mappings
@@ -90,7 +92,7 @@ func (region *TORegion) Read(db *sqlx.DB, parameters map[string]string, user aut
 	query := selectQuery() + where + orderBy
 	log.Debugln("Query is ", query)
 
-	rows, err := db.NamedQuery(query, queryValues)
+	rows, err := region.ReqInfo.Tx.NamedQuery(query, queryValues)
 	if err != nil {
 		log.Errorf("Error querying Regions: %v", err)
 		return nil, []error{tc.DBError}, tc.SystemError
@@ -128,25 +130,9 @@ JOIN division d ON r.division = d.id`
 //ParsePQUniqueConstraintError is used to determine if a region with conflicting values exists
 //if so, it will return an errorType of DataConflict and the type should be appended to the
 //generic error message returned
-func (region *TORegion) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
-	rollbackTransaction := true
-	tx, err := db.Beginx()
-	defer func() {
-		if tx == nil || !rollbackTransaction {
-			return
-		}
-		err := tx.Rollback()
-		if err != nil {
-			log.Errorln(errors.New("rolling back transaction: " + err.Error()))
-		}
-	}()
-
-	if err != nil {
-		log.Error.Printf("could not begin transaction: %v", err)
-		return tc.DBError, tc.SystemError
-	}
+func (region *TORegion) Update() (error, tc.ApiErrorType) {
 	log.Debugf("about to run exec query: %s with region: %++v", updateQuery(), region)
-	resultRows, err := tx.NamedQuery(updateQuery(), region)
+	resultRows, err := region.ReqInfo.Tx.NamedQuery(updateQuery(), region)
 	if err != nil {
 		if pqErr, ok := err.(*pq.Error); ok {
 			err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
@@ -177,12 +163,7 @@ func (region *TORegion) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.Ap
 		}
 		return fmt.Errorf("this update affected too many rows: %d", rowsAffected), tc.SystemError
 	}
-	err = tx.Commit()
-	if err != nil {
-		log.Errorln("Could not commit transaction: ", err)
-		return tc.DBError, tc.SystemError
-	}
-	rollbackTransaction = false
+
 	return nil, tc.NoError
 }
 
@@ -193,24 +174,8 @@ func (region *TORegion) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.Ap
 //generic error message returned
 //The insert sql returns the id and lastUpdated values of the newly inserted region and have
 //to be added to the struct
-func (region *TORegion) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
-	rollbackTransaction := true
-	tx, err := db.Beginx()
-	defer func() {
-		if tx == nil || !rollbackTransaction {
-			return
-		}
-		err := tx.Rollback()
-		if err != nil {
-			log.Errorln(errors.New("rolling back transaction: " + err.Error()))
-		}
-	}()
-
-	if err != nil {
-		log.Error.Printf("could not begin transaction: %v", err)
-		return tc.DBError, tc.SystemError
-	}
-	resultRows, err := tx.NamedQuery(insertQuery(), region)
+func (region *TORegion) Create() (error, tc.ApiErrorType) {
+	resultRows, err := region.ReqInfo.Tx.NamedQuery(insertQuery(), region)
 	if err != nil {
 		if pqErr, ok := err.(*pq.Error); ok {
 			err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
@@ -246,36 +211,15 @@ func (region *TORegion) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.Ap
 	}
 	region.SetKeys(map[string]interface{}{"id": id})
 	region.LastUpdated = lastUpdated
-	err = tx.Commit()
-	if err != nil {
-		log.Errorln("Could not commit transaction: ", err)
-		return tc.DBError, tc.SystemError
-	}
-	rollbackTransaction = false
+
 	return nil, tc.NoError
 }
 
 //The Region implementation of the Deleter interface
 //all implementations of Deleter should use transactions and return the proper errorType
-func (region *TORegion) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
-	rollbackTransaction := true
-	tx, err := db.Beginx()
-	defer func() {
-		if tx == nil || !rollbackTransaction {
-			return
-		}
-		err := tx.Rollback()
-		if err != nil {
-			log.Errorln(errors.New("rolling back transaction: " + err.Error()))
-		}
-	}()
-
-	if err != nil {
-		log.Error.Printf("could not begin transaction: %v", err)
-		return tc.DBError, tc.SystemError
-	}
+func (region *TORegion) Delete() (error, tc.ApiErrorType) {
 	log.Debugf("about to run exec query: %s with region: %++v", deleteQuery(), region)
-	result, err := tx.NamedExec(deleteQuery(), region)
+	result, err := region.ReqInfo.Tx.NamedExec(deleteQuery(), region)
 	if err != nil {
 		log.Errorf("received error: %++v from delete execution", err)
 		return tc.DBError, tc.SystemError
@@ -291,12 +235,6 @@ func (region *TORegion) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.Ap
 		return fmt.Errorf("this create affected too many rows: %d", rowsAffected), tc.SystemError
 	}
 
-	err = tx.Commit()
-	if err != nil {
-		log.Errorln("Could not commit transaction: ", err)
-		return tc.DBError, tc.SystemError
-	}
-	rollbackTransaction = false
 	return nil, tc.NoError
 }
 
diff --git a/traffic_ops/traffic_ops_golang/region/regions_test.go b/traffic_ops/traffic_ops_golang/region/regions_test.go
index 854f838..ad7cb6c 100644
--- a/traffic_ops/traffic_ops_golang/region/regions_test.go
+++ b/traffic_ops/traffic_ops_golang/region/regions_test.go
@@ -24,8 +24,8 @@ import (
 	"time"
 
 	"github.com/apache/trafficcontrol/lib/go-tc"
+	"github.com/apache/trafficcontrol/lib/go-util"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
-	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/auth"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/test"
 	"github.com/jmoiron/sqlx"
 
@@ -59,8 +59,6 @@ func TestReadRegions(t *testing.T) {
 	db := sqlx.NewDb(mockDB, "sqlmock")
 	defer db.Close()
 
-	refType := GetRefType()
-
 	testRegions := getTestRegions()
 	cols := test.ColsFromStructByTag("db", tc.Region{})
 	rows := sqlmock.NewRows(cols)
@@ -73,10 +71,14 @@ func TestReadRegions(t *testing.T) {
 			ts.Name,
 		)
 	}
+	mock.ExpectBegin()
 	mock.ExpectQuery("SELECT").WillReturnRows(rows)
+	mock.ExpectCommit()
 	v := map[string]string{"id": "1"}
 
-	regions, errs, _ := refType.Read(db, v, auth.CurrentUser{})
+	reqInfo := api.APIInfo{Tx:db.MustBegin(),CommitTx:util.BoolPtr(false)}
+
+	regions, errs, _ := GetTypeSingleton()(&reqInfo).Read(v)
 	if len(errs) > 0 {
 		t.Errorf("region.Read expected: no errors, actual: %v", errs)
 	}
diff --git a/traffic_ops/traffic_ops_golang/role/roles.go b/traffic_ops/traffic_ops_golang/role/roles.go
index 3871c8b..2cc8a37 100644
--- a/traffic_ops/traffic_ops_golang/role/roles.go
+++ b/traffic_ops/traffic_ops_golang/role/roles.go
@@ -29,7 +29,6 @@ import (
 	"github.com/apache/trafficcontrol/lib/go-tc/tovalidate"
 	"github.com/apache/trafficcontrol/lib/go-tc/v13"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
-	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/auth"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/dbhelpers"
 
 	validation "github.com/go-ozzo/ozzo-validation"
@@ -38,13 +37,16 @@ import (
 )
 
 //we need a type alias to define functions on
-type TORole v13.Role
-
-//the refType is passed into the handlers where a copy of its type is used to decode the json.
-var refType = TORole{}
+type TORole struct{
+	ReqInfo *api.APIInfo `json:"-"`
+	v13.Role
+}
 
-func GetRefType() *TORole {
-	return &refType
+func GetTypeSingleton() func(reqInfo *api.APIInfo)api.CRUDer {
+	return func(reqInfo *api.APIInfo)api.CRUDer {
+		toReturn := TORole{reqInfo, v13.Role{}}
+		return &toReturn
+	}
 }
 
 func (role TORole) GetKeyFieldsInfo() []api.KeyFieldInfo {
@@ -79,7 +81,7 @@ func (role *TORole) SetKeys(keys map[string]interface{}) {
 }
 
 // Validate fulfills the api.Validator interface
-func (role TORole) Validate(db *sqlx.DB) []error {
+func (role TORole) Validate() []error {
 	errs := validation.Errors{
 		"name":        validation.Validate(role.Name, validation.Required),
 		"description": validation.Validate(role.Description, validation.Required),
@@ -88,8 +90,8 @@ func (role TORole) Validate(db *sqlx.DB) []error {
 	errsToReturn := tovalidate.ToErrors(errs)
 	checkCaps := `SELECT cap FROM UNNEST($1::text[]) AS cap WHERE NOT cap =  ANY(ARRAY(SELECT c.name FROM capability AS c WHERE c.name = ANY($1)))`
 	var badCaps []string
-	if db != nil {
-		err := db.Select(&badCaps, checkCaps, pq.Array(role.Capabilities))
+	if role.ReqInfo.Tx != nil {
+		err := role.ReqInfo.Tx.Select(&badCaps, checkCaps, pq.Array(role.Capabilities))
 		if err != nil {
 			log.Errorf("got error from selecting bad capabilities: %v", err)
 			return []error{tc.DBError}
@@ -108,27 +110,11 @@ func (role TORole) Validate(db *sqlx.DB) []error {
 //generic error message returned
 //The insert sql returns the id and lastUpdated values of the newly inserted role and have
 //to be added to the struct
-func (role *TORole) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
-	rollbackTransaction := true
-	tx, err := db.Beginx()
-	defer func() {
-		if tx == nil || !rollbackTransaction {
-			return
-		}
-		err := tx.Rollback()
-		if err != nil {
-			log.Errorln(errors.New("rolling back transaction: " + err.Error()))
-		}
-	}()
-
-	if err != nil {
-		log.Error.Printf("could not begin transaction: %v", err)
-		return tc.DBError, tc.SystemError
-	}
-	if *role.PrivLevel > user.PrivLevel {
+func (role *TORole) Create() (error, tc.ApiErrorType) {
+	if *role.PrivLevel > role.ReqInfo.User.PrivLevel {
 		return errors.New("can not create a role with a higher priv level than your own"), tc.ForbiddenError
 	}
-	resultRows, err := tx.NamedQuery(insertQuery(), role)
+	resultRows, err := role.ReqInfo.Tx.NamedQuery(insertQuery(), role)
 	if err != nil {
 		if pqErr, ok := err.(*pq.Error); ok {
 			err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
@@ -163,17 +149,11 @@ func (role *TORole) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErr
 	}
 	role.SetKeys(map[string]interface{}{"id": id})
 	//after we have role ID we can associate the capabilities:
-	err, errType := role.createRoleCapabilityAssociations(tx)
+	err, errType := role.createRoleCapabilityAssociations(role.ReqInfo.Tx)
 	if err != nil {
 		return err, errType
 	}
 
-	err = tx.Commit()
-	if err != nil {
-		log.Errorln("Could not commit transaction: ", err)
-		return tc.DBError, tc.SystemError
-	}
-	rollbackTransaction = false
 	return nil, tc.NoError
 }
 
@@ -209,7 +189,7 @@ func (role *TORole) deleteRoleCapabilityAssociations(tx *sqlx.Tx) (error, tc.Api
 	return nil, tc.NoError
 }
 
-func (role *TORole) Read(db *sqlx.DB, parameters map[string]string, user auth.CurrentUser) ([]interface{}, []error, tc.ApiErrorType) {
+func (role *TORole) Read(parameters map[string]string) ([]interface{}, []error, tc.ApiErrorType) {
 	var rows *sqlx.Rows
 
 	// Query Parameters to Database Query column mappings
@@ -226,7 +206,7 @@ func (role *TORole) Read(db *sqlx.DB, parameters map[string]string, user auth.Cu
 	query := selectQuery() + where + orderBy
 	log.Debugln("Query is ", query)
 
-	rows, err := db.NamedQuery(query, queryValues)
+	rows, err := role.ReqInfo.Tx.NamedQuery(query, queryValues)
 	if err != nil {
 		log.Errorf("Error querying Roles: %v", err)
 		return nil, []error{tc.DBError}, tc.SystemError
@@ -253,30 +233,13 @@ func (role *TORole) Read(db *sqlx.DB, parameters map[string]string, user auth.Cu
 //ParsePQUniqueConstraintError is used to determine if a role with conflicting values exists
 //if so, it will return an errorType of DataConflict and the type should be appended to the
 //generic error message returned
-func (role *TORole) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
-	rollbackTransaction := true
-	tx, err := db.Beginx()
-	defer func() {
-		if tx == nil || !rollbackTransaction {
-			return
-		}
-		err := tx.Rollback()
-		if err != nil {
-			log.Errorln(errors.New("rolling back transaction: " + err.Error()))
-		}
-	}()
-
-	if err != nil {
-		log.Error.Printf("could not begin transaction: %v", err)
-		return tc.DBError, tc.SystemError
-	}
-
-	if *role.PrivLevel > user.PrivLevel {
+func (role *TORole) Update() (error, tc.ApiErrorType) {
+	if *role.PrivLevel > role.ReqInfo.User.PrivLevel {
 		return errors.New("can not create a role with a higher priv level than your own"), tc.ForbiddenError
 	}
 
 	log.Debugf("about to run exec query: %s with role: %++v\n", updateQuery(), role)
-	result, err := tx.NamedExec(updateQuery(), role)
+	result, err := role.ReqInfo.Tx.NamedExec(updateQuery(), role)
 	if err != nil {
 		if pqErr, ok := err.(*pq.Error); ok {
 			err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
@@ -303,46 +266,24 @@ func (role *TORole) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErr
 		}
 	}
 	//remove associations
-	err, errType := role.deleteRoleCapabilityAssociations(tx)
+	err, errType := role.deleteRoleCapabilityAssociations(role.ReqInfo.Tx)
 	if err != nil {
 		return err, errType
 	}
 	//create new associations
-	err, errType = role.createRoleCapabilityAssociations(tx)
+	err, errType = role.createRoleCapabilityAssociations(role.ReqInfo.Tx)
 	if err != nil {
 		return err, errType
 	}
 
-	err = tx.Commit()
-	if err != nil {
-		log.Errorln("Could not commit transaction: ", err)
-		return tc.DBError, tc.SystemError
-	}
-	rollbackTransaction = false
 	return nil, tc.NoError
 }
 
 //The Role implementation of the Deleter interface
 //all implementations of Deleter should use transactions and return the proper errorType
-func (role *TORole) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
-	rollbackTransaction := true
-	tx, err := db.Beginx()
-	defer func() {
-		if tx == nil || !rollbackTransaction {
-			return
-		}
-		err := tx.Rollback()
-		if err != nil {
-			log.Errorln(errors.New("rolling back transaction: " + err.Error()))
-		}
-	}()
-
-	if err != nil {
-		log.Error.Printf("could not begin transaction: %v", err)
-		return tc.DBError, tc.SystemError
-	}
+func (role *TORole) Delete() (error, tc.ApiErrorType) {
 	assignedUsers := 0
-	err = tx.Get(&assignedUsers, "SELECT COUNT(id) FROM tm_user WHERE role=$1", role.ID)
+	err := role.ReqInfo.Tx.Get(&assignedUsers, "SELECT COUNT(id) FROM tm_user WHERE role=$1", role.ID)
 	if err != nil {
 		log.Errorf("received error: %++v from assigned users check", err)
 		return tc.DBError, tc.SystemError
@@ -352,7 +293,7 @@ func (role *TORole) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErr
 	}
 
 	log.Debugf("about to run exec query: %s with role: %++v", deleteQuery(), role)
-	result, err := tx.NamedExec(deleteQuery(), role)
+	result, err := role.ReqInfo.Tx.NamedExec(deleteQuery(), role)
 	if err != nil {
 		log.Errorf("received error: %++v from delete execution", err)
 		return tc.DBError, tc.SystemError
@@ -369,17 +310,11 @@ func (role *TORole) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErr
 		}
 	}
 	//remove associations
-	err, errType := role.deleteRoleCapabilityAssociations(tx)
+	err, errType := role.deleteRoleCapabilityAssociations(role.ReqInfo.Tx)
 	if err != nil {
 		return err, errType
 	}
 
-	err = tx.Commit()
-	if err != nil {
-		log.Errorln("Could not commit transaction: ", err)
-		return tc.DBError, tc.SystemError
-	}
-	rollbackTransaction = false
 	return nil, tc.NoError
 }
 
diff --git a/traffic_ops/traffic_ops_golang/role/roles_test.go b/traffic_ops/traffic_ops_golang/role/roles_test.go
index 0c49961..7807371 100644
--- a/traffic_ops/traffic_ops_golang/role/roles_test.go
+++ b/traffic_ops/traffic_ops_golang/role/roles_test.go
@@ -96,8 +96,9 @@ func TestInterfaces(t *testing.T) {
 func TestValidate(t *testing.T) {
 	// invalid name, empty domainname
 	n := "not_a_valid_role"
-	r := TORole{Name: &n}
-	errs := test.SortErrors(r.Validate(nil))
+	reqInfo := api.APIInfo{}
+	r := TORole{ReqInfo: &reqInfo, Role: v13.Role{Name: &n}}
+	errs := test.SortErrors(r.Validate())
 
 	expectedErrs := []error{
 		errors.New(`'description' cannot be blank`),
@@ -109,9 +110,9 @@ func TestValidate(t *testing.T) {
 	}
 
 	//  name,  domainname both valid
-	r = TORole{Name: stringAddr("this is a valid name"), Description: stringAddr("this is a description"), PrivLevel: intAddr(30)}
+	r = TORole{ReqInfo: &reqInfo, Role: v13.Role{Name: stringAddr("this is a valid name"), Description: stringAddr("this is a description"), PrivLevel: intAddr(30)}}
 	expectedErrs = []error{}
-	errs = r.Validate(nil)
+	errs = r.Validate()
 	if !reflect.DeepEqual(expectedErrs, errs) {
 		t.Errorf("expected %s, got %s", expectedErrs, errs)
 	}
diff --git a/traffic_ops/traffic_ops_golang/routes.go b/traffic_ops/traffic_ops_golang/routes.go
index ed93d74..00edc23 100644
--- a/traffic_ops/traffic_ops_golang/routes.go
+++ b/traffic_ops/traffic_ops_golang/routes.go
@@ -46,16 +46,16 @@ import (
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/division"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/hwinfo"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/origin"
-	//"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/parameter"
-	//"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/physlocation"
+	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/parameter"
+	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/physlocation"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/ping"
-	//"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/profile"
+	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/profile"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/profileparameter"
-	//"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/region"
-	//"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/role"
+	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/region"
+	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/role"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/server"
-	//"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/staticdnsentry"
-	//"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/status"
+	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/staticdnsentry"
+	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/status"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/systeminfo"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/tenant"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/types"
@@ -139,37 +139,37 @@ func Routes(d ServerData) ([]Route, []RawRoute, http.Handler, error) {
 		{1.2, http.MethodPost, `user/login/?$`, wrapAccessLog(d.Secrets[0], auth.LoginHandler(d.DB, d.Config)), 0, NoAuth, nil}, {1.3, http.MethodPost, `user/login/?$`, auth.LoginHandler(d.DB, d.Config), 0, NoAuth, nil},
 
 		//Parameter: CRUD
-		//{1.1, http.MethodGet, `parameters/?(\.json)?$`, api.ReadHandler(parameter.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
-		//{1.1, http.MethodGet, `parameters/{id}$`, api.ReadHandler(parameter.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
-		//{1.1, http.MethodPut, `parameters/{id}$`, api.UpdateHandler(parameter.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
-		//{1.1, http.MethodPost, `parameters/?$`, api.CreateHandler(parameter.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
-		//{1.1, http.MethodDelete, `parameters/{id}$`, api.DeleteHandler(parameter.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
+		{1.1, http.MethodGet, `parameters/?(\.json)?$`, api.ReadHandler(parameter.GetTypeSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
+		{1.1, http.MethodGet, `parameters/{id}$`, api.ReadHandler(parameter.GetTypeSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
+		{1.1, http.MethodPut, `parameters/{id}$`, api.UpdateHandler(parameter.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
+		{1.1, http.MethodPost, `parameters/?$`, api.CreateHandler(parameter.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
+		{1.1, http.MethodDelete, `parameters/{id}$`, api.DeleteHandler(parameter.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
 
 		//Phys_Location: CRUD
-		//{1.1, http.MethodGet, `phys_locations/?(\.json)?$`, api.ReadHandler(physlocation.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
-		//{1.1, http.MethodGet, `phys_locations/trimmed/?(\.json)?$`, physlocation.GetTrimmed(d.DB.DB), auth.PrivLevelReadOnly, Authenticated, nil},
-		//{1.1, http.MethodGet, `phys_locations/{id}$`, api.ReadHandler(physlocation.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
-		//{1.1, http.MethodPut, `phys_locations/{id}$`, api.UpdateHandler(physlocation.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
-		//{1.1, http.MethodPost, `phys_locations/?$`, api.CreateHandler(physlocation.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
-		//{1.1, http.MethodDelete, `phys_locations/{id}$`, api.DeleteHandler(physlocation.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
+		{1.1, http.MethodGet, `phys_locations/?(\.json)?$`, api.ReadHandler(physlocation.GetTypeSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
+		{1.1, http.MethodGet, `phys_locations/trimmed/?(\.json)?$`, physlocation.GetTrimmed(d.DB.DB), auth.PrivLevelReadOnly, Authenticated, nil},
+		{1.1, http.MethodGet, `phys_locations/{id}$`, api.ReadHandler(physlocation.GetTypeSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
+		{1.1, http.MethodPut, `phys_locations/{id}$`, api.UpdateHandler(physlocation.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
+		{1.1, http.MethodPost, `phys_locations/?$`, api.CreateHandler(physlocation.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
+		{1.1, http.MethodDelete, `phys_locations/{id}$`, api.DeleteHandler(physlocation.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
 
 		//Ping
 		{1.1, http.MethodGet, `ping$`, ping.PingHandler(), 0, NoAuth, nil},
 
 		//Profile: CRUD
-		//{1.1, http.MethodGet, `profiles/?(\.json)?$`, api.ReadHandler(profile.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
-		//{1.1, http.MethodGet, `profiles/trimmed/?(\.json)?$`, profile.Trimmed(d.DB.DB), auth.PrivLevelReadOnly, Authenticated, nil},
-		//{1.1, http.MethodGet, `profiles/{id}$`, api.ReadHandler(profile.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
-		//{1.1, http.MethodPut, `profiles/{id}$`, api.UpdateHandler(profile.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
-		//{1.1, http.MethodPost, `profiles/?$`, api.CreateHandler(profile.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
-		//{1.1, http.MethodDelete, `profiles/{id}$`, api.DeleteHandler(profile.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
-
-		//Region: CRUD
-		//{1.1, http.MethodGet, `regions/?(\.json)?$`, api.ReadHandler(region.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
-		//{1.1, http.MethodGet, `regions/{id}$`, api.ReadHandler(region.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
-		//{1.1, http.MethodPut, `regions/{id}$`, api.UpdateHandler(region.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
-		//{1.1, http.MethodPost, `regions/?$`, api.CreateHandler(region.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
-		//{1.1, http.MethodDelete, `regions/{id}$`, api.DeleteHandler(region.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
+		{1.1, http.MethodGet, `profiles/?(\.json)?$`, api.ReadHandler(profile.GetTypeSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
+		{1.1, http.MethodGet, `profiles/trimmed/?(\.json)?$`, profile.Trimmed(d.DB.DB), auth.PrivLevelReadOnly, Authenticated, nil},
+		{1.1, http.MethodGet, `profiles/{id}$`, api.ReadHandler(profile.GetTypeSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
+		{1.1, http.MethodPut, `profiles/{id}$`, api.UpdateHandler(profile.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
+		{1.1, http.MethodPost, `profiles/?$`, api.CreateHandler(profile.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
+		{1.1, http.MethodDelete, `profiles/{id}$`, api.DeleteHandler(profile.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
+
+		//Region: CRUDs
+		{1.1, http.MethodGet, `regions/?(\.json)?$`, api.ReadHandler(region.GetTypeSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
+		{1.1, http.MethodGet, `regions/{id}$`, api.ReadHandler(region.GetTypeSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
+		{1.1, http.MethodPut, `regions/{id}$`, api.UpdateHandler(region.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
+		{1.1, http.MethodPost, `regions/?$`, api.CreateHandler(region.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
+		{1.1, http.MethodDelete, `regions/{id}$`, api.DeleteHandler(region.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
 
 		{1.1, http.MethodDelete, `deliveryservice_server/{dsid}/{serverid}`, dsserver.Delete, auth.PrivLevelReadOnly, Authenticated, nil},
 
@@ -178,10 +178,10 @@ func Routes(d ServerData) ([]Route, []RawRoute, http.Handler, error) {
 		{1.1, http.MethodGet, `deliveryserviceserver$`, dsserver.ReadDSSHandler(d.DB),auth.PrivLevelReadOnly, Authenticated, nil},
 		{1.1, http.MethodPost,`deliveryserviceserver$`, dsserver.GetReplaceHandler(d.DB),auth.PrivLevelOperations, Authenticated, nil},
 		{1.1, http.MethodPost,`deliveryservices/{xml_id}/servers$`, dsserver.GetCreateHandler( d.DB ) ,auth.PrivLevelOperations, Authenticated, nil},
-		//{1.1, http.MethodGet, `servers/{id}/deliveryservices$`, api.ReadHandler(dsserver.GetDServiceRef(), d.DB),auth.PrivLevelReadOnly, Authenticated, nil},
+		{1.1, http.MethodGet, `servers/{id}/deliveryservices$`, api.ReadOnlyHandler(dsserver.GetDSSDeliveryServiceReaderSingleton()),auth.PrivLevelReadOnly, Authenticated, nil},
 		{1.1, http.MethodGet, `deliveryservices/{id}/servers$`, dsserver.GetReadHandler(d.DB, tc.Assigned),auth.PrivLevelReadOnly, Authenticated, nil},
 		{1.1, http.MethodGet, `deliveryservices/{id}/unassigned_servers$`, dsserver.GetReadHandler(d.DB, tc.Unassigned),auth.PrivLevelReadOnly, Authenticated, nil},
-		////{1.1, http.MethodGet, `deliveryservices/{id}/servers/eligible$`, dsserver.GetReadHandler(d.Tx, tc.Eligible),auth.PrivLevelReadOnly, Authenticated, nil},
+		//{1.1, http.MethodGet, `deliveryservices/{id}/servers/eligible$`, dsserver.GetReadHandler(d.Tx, tc.Eligible),auth.PrivLevelReadOnly, Authenticated, nil},
 
 		//Server
 		{1.1, http.MethodGet, `servers/checks$`, handlerToFunc(proxyHandler), 0, NoAuth, []Middleware{}},
@@ -193,28 +193,28 @@ func Routes(d ServerData) ([]Route, []RawRoute, http.Handler, error) {
 		{1.2, http.MethodGet, `servers/hostname/{hostName}/details/?(\.json)?$`, server.GetDetailHandler(d.DB.DB), auth.PrivLevelReadOnly, Authenticated, nil},
 
 		//Server: CRUD
-		//{1.1, http.MethodGet, `servers/?(\.json)?$`, api.ReadHandler(server.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
-		//{1.1, http.MethodGet, `servers/{id}$`, api.ReadHandler(server.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
-		//{1.1, http.MethodPut, `servers/{id}$`, api.UpdateHandler(server.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
-		//{1.1, http.MethodPost, `servers/?$`, api.CreateHandler(server.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
-		//{1.1, http.MethodDelete, `servers/{id}$`, api.DeleteHandler(server.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
+		{1.1, http.MethodGet, `servers/?(\.json)?$`, api.ReadHandler(server.GetTypeSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
+		{1.1, http.MethodGet, `servers/{id}$`, api.ReadHandler(server.GetTypeSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
+		{1.1, http.MethodPut, `servers/{id}$`, api.UpdateHandler(server.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
+		{1.1, http.MethodPost, `servers/?$`, api.CreateHandler(server.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
+		{1.1, http.MethodDelete, `servers/{id}$`, api.DeleteHandler(server.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
 
 		//Status: CRUD
-		//{1.1, http.MethodGet, `statuses/?(\.json)?$`, api.ReadHandler(status.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
-		//{1.1, http.MethodGet, `statuses/{id}$`, api.ReadHandler(status.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
-		//{1.1, http.MethodPut, `statuses/{id}$`, api.UpdateHandler(status.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
-		//{1.1, http.MethodPost, `statuses/?$`, api.CreateHandler(status.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
-		//{1.1, http.MethodDelete, `statuses/{id}$`, api.DeleteHandler(status.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
+		{1.1, http.MethodGet, `statuses/?(\.json)?$`, api.ReadHandler(status.GetTypeSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
+		{1.1, http.MethodGet, `statuses/{id}$`, api.ReadHandler(status.GetTypeSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
+		{1.1, http.MethodPut, `statuses/{id}$`, api.UpdateHandler(status.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
+		{1.1, http.MethodPost, `statuses/?$`, api.CreateHandler(status.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
+		{1.1, http.MethodDelete, `statuses/{id}$`, api.DeleteHandler(status.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
 
 		//System
 		{1.1, http.MethodGet, `system/info/?(\.json)?$`, systeminfo.Handler(d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
 
 		//Type: CRUD
-		//{1.1, http.MethodGet, `types/?(\.json)?$`, api.ReadHandler(types.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
-		//{1.1, http.MethodGet, `types/{id}$`, api.ReadHandler(types.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
-		//{1.1, http.MethodPut, `types/{id}$`, api.UpdateHandler(types.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
-		//{1.1, http.MethodPost, `types/?$`, api.CreateHandler(types.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
-		//{1.1, http.MethodDelete, `types/{id}$`, api.DeleteHandler(types.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
+		{1.1, http.MethodGet, `types/?(\.json)?$`, api.ReadHandler(types.GetTypeSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
+		{1.1, http.MethodGet, `types/{id}$`, api.ReadHandler(types.GetTypeSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
+		{1.1, http.MethodPut, `types/{id}$`, api.UpdateHandler(types.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
+		{1.1, http.MethodPost, `types/?$`, api.CreateHandler(types.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
+		{1.1, http.MethodDelete, `types/{id}$`, api.DeleteHandler(types.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
 
 		//About
 		{1.3, http.MethodGet, `about/?(\.json)?$`, about.Handler(), auth.PrivLevelReadOnly, Authenticated, nil},
@@ -280,10 +280,10 @@ func Routes(d ServerData) ([]Route, []RawRoute, http.Handler, error) {
 		{1.3, http.MethodDelete, `origins/?$`, api.DeleteHandler(origin.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
 
 		//Roles
-		//{1.3, http.MethodGet, `roles/?(\.json)?$`, api.ReadHandler(role.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
-		//{1.3, http.MethodPut, `roles/?$`, api.UpdateHandler(role.GetRefType(), d.DB), auth.PrivLevelAdmin, Authenticated, nil},
-		//{1.3, http.MethodPost, `roles/?$`, api.CreateHandler(role.GetRefType(), d.DB), auth.PrivLevelAdmin, Authenticated, nil},
-		//{1.3, http.MethodDelete, `roles/?$`, api.DeleteHandler(role.GetRefType(), d.DB), auth.PrivLevelAdmin, Authenticated, nil},
+		{1.3, http.MethodGet, `roles/?(\.json)?$`, api.ReadHandler(role.GetTypeSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
+		{1.3, http.MethodPut, `roles/?$`, api.UpdateHandler(role.GetTypeSingleton()), auth.PrivLevelAdmin, Authenticated, nil},
+		{1.3, http.MethodPost, `roles/?$`, api.CreateHandler(role.GetTypeSingleton()), auth.PrivLevelAdmin, Authenticated, nil},
+		{1.3, http.MethodDelete, `roles/?$`, api.DeleteHandler(role.GetTypeSingleton()), auth.PrivLevelAdmin, Authenticated, nil},
 
 		//Delivery Services Regexes
 		{1.1, http.MethodGet, `deliveryservices_regexes/?(\.json)?$`, deliveryservicesregexes.Get(d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
@@ -297,20 +297,20 @@ func Routes(d ServerData) ([]Route, []RawRoute, http.Handler, error) {
 		{1.3, http.MethodPost, `servers/{id}/deliveryservices$`, server.AssignDeliveryServicesToServerHandler(d.DB), auth.PrivLevelOperations, Authenticated, nil},
 		{1.3, http.MethodGet, `servers/{host_name}/update_status$`, server.GetServerUpdateStatusHandler(d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
 
-		//{1.1, http.MethodGet, `staticdnsentries/?(\.json)?$`, api.ReadHandler(staticdnsentry.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
+		{1.1, http.MethodGet, `staticdnsentries/?(\.json)?$`, api.ReadOnlyHandler(staticdnsentry.GetReaderSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
 
 		//ProfileParameters
 		{1.1, http.MethodGet, `profiles/{id}/parameters/?(\.json)?$`, profileparameter.GetProfileID(d.DB.DB), auth.PrivLevelReadOnly, Authenticated, nil},
 		{1.1, http.MethodGet, `profiles/{id}/unassigned_parameters/?(\.json)?$`, profileparameter.GetUnassigned(d.DB.DB), auth.PrivLevelReadOnly, Authenticated, nil},
 		{1.1, http.MethodGet, `profiles/name/{name}/parameters/?(\.json)?$`, profileparameter.GetProfileName(d.DB.DB), auth.PrivLevelReadOnly, Authenticated, nil},
 		{1.1, http.MethodGet, `parameters/profile/{name}/?(\.json)?$`, profileparameter.GetProfileName(d.DB.DB), auth.PrivLevelReadOnly, Authenticated, nil},
-		{1.1, http.MethodPost, `profiles/name/{name}/parameters/?$`, profileparameter.PostProfileParamsByName, auth.PrivLevelOperations, Authenticated, nil},
-		{1.1, http.MethodPost, `profiles/{id}/parameters/?$`, profileparameter.PostProfileParamsByID, auth.PrivLevelOperations, Authenticated, nil},
-		{1.1, http.MethodGet, `profileparameters/?(\.json)?$`, api.ReadHandler(profileparameter.GetRefType(), d.DB), auth.PrivLevelReadOnly, Authenticated, nil},
-		{1.1, http.MethodPost, `profileparameters/?$`, api.CreateHandler(profileparameter.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
-		{1.1, http.MethodPost, `profileparameter/?$`, profileparameter.PostProfileParam, auth.PrivLevelOperations, Authenticated, nil},
-		{1.1, http.MethodPost, `parameterprofile/?$`, profileparameter.PostParamProfile, auth.PrivLevelOperations, Authenticated, nil},
-		{1.1, http.MethodDelete, `profileparameters/{profileId}/{parameterId}$`, api.DeleteHandler(profileparameter.GetRefType(), d.DB), auth.PrivLevelOperations, Authenticated, nil},
+		{1.1, http.MethodPost, `profiles/name/{name}/parameters/?$`, profileparameter.PostProfileParamsByName(d.DB.DB), auth.PrivLevelOperations, Authenticated, nil},
+		{1.1, http.MethodPost, `profiles/{id}/parameters/?$`, profileparameter.PostProfileParamsByID(d.DB.DB), auth.PrivLevelOperations, Authenticated, nil},
+		{1.1, http.MethodGet, `profileparameters/?(\.json)?$`, api.ReadHandler(profileparameter.GetTypeSingleton()), auth.PrivLevelReadOnly, Authenticated, nil},
+		{1.1, http.MethodPost, `profileparameters/?$`, api.CreateHandler(profileparameter.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
+		{1.1, http.MethodPost, `profileparameter/?$`, profileparameter.PostProfileParam(d.DB.DB), auth.PrivLevelOperations, Authenticated, nil},
+		{1.1, http.MethodPost, `parameterprofile/?$`, profileparameter.PostParamProfile(d.DB.DB), auth.PrivLevelOperations, Authenticated, nil},
+		{1.1, http.MethodDelete, `profileparameters/{profileId}/{parameterId}$`, api.DeleteHandler(profileparameter.GetTypeSingleton()), auth.PrivLevelOperations, Authenticated, nil},
 
 
 		//Tenants
diff --git a/traffic_ops/traffic_ops_golang/server/servers.go b/traffic_ops/traffic_ops_golang/server/servers.go
index cd82dc8..1ad8eea 100644
--- a/traffic_ops/traffic_ops_golang/server/servers.go
+++ b/traffic_ops/traffic_ops_golang/server/servers.go
@@ -39,13 +39,16 @@ import (
 )
 
 //we need a type alias to define functions on
-type TOServer v13.ServerNullable
-
-//the refType is passed into the handlers where a copy of its type is used to decode the json.
-var refType = TOServer{}
+type TOServer struct{
+	ReqInfo *api.APIInfo `json:"-"`
+	v13.ServerNullable
+}
 
-func GetRefType() *TOServer {
-	return &refType
+func GetTypeSingleton() func(reqInfo *api.APIInfo)api.CRUDer {
+	return func(reqInfo *api.APIInfo)api.CRUDer {
+		toReturn := TOServer{reqInfo, v13.ServerNullable{}}
+		return &toReturn
+	}
 }
 
 func (server TOServer) GetKeyFieldsInfo() []api.KeyFieldInfo {
@@ -79,7 +82,7 @@ func (server *TOServer) GetType() string {
 	return "server"
 }
 
-func (server *TOServer) Validate(db *sqlx.DB) []error {
+func (server *TOServer) Validate() []error {
 
 	noSpaces := validation.NewStringRule(tovalidate.NoSpaces, "cannot contain spaces")
 
@@ -104,7 +107,7 @@ func (server *TOServer) Validate(db *sqlx.DB) []error {
 		return errs
 	}
 
-	rows, err := db.Query("select use_in_table from type where id=$1", server.TypeID)
+	rows, err := server.ReqInfo.Tx.Query("select use_in_table from type where id=$1", server.TypeID)
 	if err != nil {
 		log.Error.Printf("could not execute select use_in_table from type: %s\n", err)
 		errs = append(errs, tc.DBError)
@@ -123,7 +126,7 @@ func (server *TOServer) Validate(db *sqlx.DB) []error {
 		errs = append(errs, errors.New("invalid server type"))
 	}
 
-	rows, err = db.Query("select cdn from profile where id=$1", server.ProfileID)
+	rows, err = server.ReqInfo.Tx.Query("select cdn from profile where id=$1", server.ProfileID)
 	if err != nil {
 		log.Error.Printf("could not execute select cdnID from profile: %s\n", err)
 		errs = append(errs, tc.DBError)
@@ -173,12 +176,12 @@ func (server TOServer) ChangeLogMessage(action string) (string, error) {
 	return message, nil
 }
 
-func (server *TOServer) Read(db *sqlx.DB, params map[string]string, user auth.CurrentUser) ([]interface{}, []error, tc.ApiErrorType) {
+func (server *TOServer) Read(params map[string]string) ([]interface{}, []error, tc.ApiErrorType) {
 	returnable := []interface{}{}
 
-	privLevel := user.PrivLevel
+	privLevel := server.ReqInfo.User.PrivLevel
 
-	servers, errs, errType := getServers(params, db, privLevel)
+	servers, errs, errType := getServers(params, server.ReqInfo.Tx, privLevel)
 	if len(errs) > 0 {
 		for _, err := range errs {
 			if err.Error() == `id cannot parse to integer` {
@@ -195,7 +198,7 @@ func (server *TOServer) Read(db *sqlx.DB, params map[string]string, user auth.Cu
 	return returnable, nil, tc.NoError
 }
 
-func getServers(params map[string]string, db *sqlx.DB, privLevel int) ([]tc.ServerNullable, []error, tc.ApiErrorType) {
+func getServers(params map[string]string, tx *sqlx.Tx, privLevel int) ([]tc.ServerNullable, []error, tc.ApiErrorType) {
 	var rows *sqlx.Rows
 	var err error
 
@@ -221,7 +224,7 @@ func getServers(params map[string]string, db *sqlx.DB, privLevel int) ([]tc.Serv
 	query := selectQuery() + where + orderBy
 	log.Debugln("Query is ", query)
 
-	rows, err = db.NamedQuery(query, queryValues)
+	rows, err = tx.NamedQuery(query, queryValues)
 	if err != nil {
 		return nil, []error{fmt.Errorf("querying: %v", err)}, tc.SystemError
 	}
@@ -313,26 +316,9 @@ JOIN type t ON s.type = t.id`
 //ParsePQUniqueConstraintError is used to determine if a cdn with conflicting values exists
 //if so, it will return an errorType of DataConflict and the type should be appended to the
 //generic error message returned
-func (server *TOServer) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
-	rollbackTransaction := true
-	tx, err := db.Beginx()
-	defer func() {
-		if tx == nil || !rollbackTransaction {
-			return
-		}
-		err := tx.Rollback()
-		if err != nil {
-			log.Errorln(errors.New("rolling back transaction: " + err.Error()))
-		}
-	}()
-
-	if err != nil {
-		log.Error.Printf("could not begin transaction: %v", err)
-		return tc.DBError, tc.SystemError
-	}
-
+func (server *TOServer) Update() (error, tc.ApiErrorType) {
 	log.Debugf("about to run exec query: %s with server: %++v", updateQuery(), server)
-	resultRows, err := tx.NamedQuery(updateQuery(), server)
+	resultRows, err := server.ReqInfo.Tx.NamedQuery(updateQuery(), server)
 	if err != nil {
 		if pqErr, ok := err.(*pq.Error); ok {
 			err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
@@ -369,12 +355,7 @@ func (server *TOServer) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.Ap
 	}
 	server.SetKeys(map[string]interface{}{"id": id})
 	server.LastUpdated = &lastUpdated
-	err = tx.Commit()
-	if err != nil {
-		log.Errorln("Could not commit transaction: ", err)
-		return tc.DBError, tc.SystemError
-	}
-	rollbackTransaction = false
+
 	return nil, tc.NoError
 }
 
@@ -424,30 +405,13 @@ WHERE id=:id RETURNING last_updated`
 //generic error message returned
 //The insert sql returns the id and lastUpdated values of the newly inserted server and have
 //to be added to the struct
-func (server *TOServer) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
-	rollbackTransaction := true
-	tx, err := db.Beginx()
-	defer func() {
-		if tx == nil || !rollbackTransaction {
-			return
-		}
-		err := tx.Rollback()
-		if err != nil {
-			log.Errorln(errors.New("rolling back transaction: " + err.Error()))
-		}
-	}()
-
-	if err != nil {
-		log.Error.Printf("could not begin transaction: %v", err)
-		return tc.DBError, tc.SystemError
-	}
-
+func (server *TOServer) Create() (error, tc.ApiErrorType) {
 	if server.XMPPID == nil || *server.XMPPID == "" {
 		hostName := *server.HostName
 		server.XMPPID = &hostName
 	}
 
-	resultRows, err := tx.NamedQuery(insertQuery(), server)
+	resultRows, err := server.ReqInfo.Tx.NamedQuery(insertQuery(), server)
 	if err != nil {
 		if pqErr, ok := err.(*pq.Error); ok {
 			err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
@@ -483,12 +447,7 @@ func (server *TOServer) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.Ap
 	}
 	server.SetKeys(map[string]interface{}{"id": id})
 	server.LastUpdated = &lastUpdated
-	err = tx.Commit()
-	if err != nil {
-		log.Errorln("Could not commit transaction: ", err)
-		return tc.DBError, tc.SystemError
-	}
-	rollbackTransaction = false
+
 	return nil, tc.NoError
 }
 
@@ -565,25 +524,9 @@ xmpp_passwd
 
 //The Server implementation of the Deleter interface
 //all implementations of Deleter should use transactions and return the proper errorType
-func (server *TOServer) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
-	rollbackTransaction := true
-	tx, err := db.Beginx()
-	defer func() {
-		if tx == nil || !rollbackTransaction {
-			return
-		}
-		err := tx.Rollback()
-		if err != nil {
-			log.Errorln(errors.New("rolling back transaction: " + err.Error()))
-		}
-	}()
-
-	if err != nil {
-		log.Error.Printf("could not begin transaction: %v", err)
-		return tc.DBError, tc.SystemError
-	}
+func (server *TOServer) Delete() (error, tc.ApiErrorType) {
 	log.Debugf("about to run exec query: %s with server: %++v", deleteServerQuery(), server)
-	result, err := tx.NamedExec(deleteServerQuery(), server)
+	result, err := server.ReqInfo.Tx.NamedExec(deleteServerQuery(), server)
 	if err != nil {
 		log.Errorf("received error: %++v from delete execution", err)
 		return tc.DBError, tc.SystemError
@@ -599,12 +542,7 @@ func (server *TOServer) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.Ap
 			return fmt.Errorf("this create affected too many rows: %d", rowsAffected), tc.SystemError
 		}
 	}
-	err = tx.Commit()
-	if err != nil {
-		log.Errorln("Could not commit transaction: ", err)
-		return tc.DBError, tc.SystemError
-	}
-	rollbackTransaction = false
+
 	return nil, tc.NoError
 }
 
diff --git a/traffic_ops/traffic_ops_golang/server/servers_test.go b/traffic_ops/traffic_ops_golang/server/servers_test.go
index bb4f008..43d4e05 100644
--- a/traffic_ops/traffic_ops_golang/server/servers_test.go
+++ b/traffic_ops/traffic_ops_golang/server/servers_test.go
@@ -157,10 +157,11 @@ func TestGetServersByCachegroup(t *testing.T) {
 			ts.XMPPPasswd,
 		)
 	}
+	mock.ExpectBegin()
 	mock.ExpectQuery("SELECT").WillReturnRows(rows)
 	v := map[string]string{"cachegroup": "2"}
 
-	servers, errs, errType := getServers(v, db, auth.PrivLevelAdmin)
+	servers, errs, errType := getServers(v, db.MustBegin(), auth.PrivLevelAdmin)
 	log.Debugln("%v-->", servers)
 	if len(errs) > 0 {
 		t.Errorf("getServers expected: no errors, actual: %v with error type: %s", errs, errType.String())
diff --git a/traffic_ops/traffic_ops_golang/staticdnsentry/staticdnsentry.go b/traffic_ops/traffic_ops_golang/staticdnsentry/staticdnsentry.go
index ac9f3b1..2c06d35 100644
--- a/traffic_ops/traffic_ops_golang/staticdnsentry/staticdnsentry.go
+++ b/traffic_ops/traffic_ops_golang/staticdnsentry/staticdnsentry.go
@@ -22,16 +22,23 @@ package staticdnsentry
 import (
 	"github.com/apache/trafficcontrol/lib/go-log"
 	"github.com/apache/trafficcontrol/lib/go-tc"
-	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/auth"
+	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/dbhelpers"
-	"github.com/jmoiron/sqlx"
 )
 
-type TOStaticDNSEntry tc.StaticDNSEntry
+type TOStaticDNSEntry struct{
+	ReqInfo *api.APIInfo `json:"-"`
+	tc.StaticDNSEntry
+}
 
-func GetRefType() *TOStaticDNSEntry { return &TOStaticDNSEntry{} }
+func GetReaderSingleton() func(reqInfo *api.APIInfo)api.Reader {
+	return func(reqInfo *api.APIInfo)api.Reader {
+		toReturn := TOStaticDNSEntry{reqInfo, tc.StaticDNSEntry{}}
+		return &toReturn
+	}
+}
 
-func (staticDNSEntry *TOStaticDNSEntry) Read(db *sqlx.DB, parameters map[string]string, user auth.CurrentUser) ([]interface{}, []error, tc.ApiErrorType) {
+func (staticDNSEntry *TOStaticDNSEntry) Read(parameters map[string]string) ([]interface{}, []error, tc.ApiErrorType) {
 	queryParamsToQueryCols := map[string]dbhelpers.WhereColumnInfo{
 		"deliveryservice": dbhelpers.WhereColumnInfo{"deliveryservice", nil}, // order by
 	}
@@ -42,7 +49,7 @@ func (staticDNSEntry *TOStaticDNSEntry) Read(db *sqlx.DB, parameters map[string]
 	}
 	query := selectQuery() + where + orderBy
 	log.Debugln("Query is ", query)
-	rows, err := db.NamedQuery(query, queryValues)
+	rows, err := staticDNSEntry.ReqInfo.Tx.NamedQuery(query, queryValues)
 	if err != nil {
 		log.Errorf("Error querying StaticDNSEntries: %v", err)
 		return nil, []error{tc.DBError}, tc.SystemError
diff --git a/traffic_ops/traffic_ops_golang/status/statuses.go b/traffic_ops/traffic_ops_golang/status/statuses.go
index a9fa43b..d00aed9 100644
--- a/traffic_ops/traffic_ops_golang/status/statuses.go
+++ b/traffic_ops/traffic_ops_golang/status/statuses.go
@@ -28,7 +28,6 @@ import (
 	"github.com/apache/trafficcontrol/lib/go-tc"
 	"github.com/apache/trafficcontrol/lib/go-tc/tovalidate"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
-	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/auth"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/dbhelpers"
 
 	validation "github.com/go-ozzo/ozzo-validation"
@@ -37,13 +36,16 @@ import (
 )
 
 //we need a type alias to define functions on
-type TOStatus tc.StatusNullable
-
-//the refType is passed into the handlers where a copy of its type is used to decode the json.
-var refType = TOStatus(tc.StatusNullable{})
+type TOStatus struct{
+	ReqInfo *api.APIInfo `json:"-"`
+	tc.StatusNullable
+}
 
-func GetRefType() *TOStatus {
-	return &refType
+func GetTypeSingleton() func(reqInfo *api.APIInfo)api.CRUDer {
+	return func(reqInfo *api.APIInfo)api.CRUDer {
+		toReturn := TOStatus{reqInfo, tc.StatusNullable{}}
+		return &toReturn
+	}
 }
 
 func (status TOStatus) GetKeyFieldsInfo() []api.KeyFieldInfo {
@@ -77,14 +79,14 @@ func (status TOStatus) GetType() string {
 	return "status"
 }
 
-func (status TOStatus) Validate(db *sqlx.DB) []error {
+func (status TOStatus) Validate() []error {
 	errs := validation.Errors{
 		"name": validation.Validate(status.Name, validation.NotNil, validation.Required),
 	}
 	return tovalidate.ToErrors(errs)
 }
 
-func (status *TOStatus) Read(db *sqlx.DB, parameters map[string]string, user auth.CurrentUser) ([]interface{}, []error, tc.ApiErrorType) {
+func (status *TOStatus) Read(parameters map[string]string) ([]interface{}, []error, tc.ApiErrorType) {
 	var rows *sqlx.Rows
 
 	// Query Parameters to Database Query column mappings
@@ -102,7 +104,7 @@ func (status *TOStatus) Read(db *sqlx.DB, parameters map[string]string, user aut
 	query := selectQuery() + where + orderBy
 	log.Debugln("Query is ", query)
 
-	rows, err := db.NamedQuery(query, queryValues)
+	rows, err := status.ReqInfo.Tx.NamedQuery(query, queryValues)
 	if err != nil {
 		log.Errorf("Error querying Status: %v", err)
 		return nil, []error{tc.DBError}, tc.SystemError
@@ -139,25 +141,9 @@ FROM status s`
 //ParsePQUniqueConstraintError is used to determine if a status with conflicting values exists
 //if so, it will return an errorType of DataConflict and the type should be appended to the
 //generic error message returned
-func (status *TOStatus) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
-	rollbackTransaction := true
-	tx, err := db.Beginx()
-	defer func() {
-		if tx == nil || !rollbackTransaction {
-			return
-		}
-		err := tx.Rollback()
-		if err != nil {
-			log.Errorln(errors.New("rolling back transaction: " + err.Error()))
-		}
-	}()
-
-	if err != nil {
-		log.Error.Printf("could not begin transaction: %v", err)
-		return tc.DBError, tc.SystemError
-	}
+func (status *TOStatus) Update() (error, tc.ApiErrorType) {
 	log.Debugf("about to run exec query: %s with status: %++v", updateQuery(), status)
-	resultRows, err := tx.NamedQuery(updateQuery(), status)
+	resultRows, err := status.ReqInfo.Tx.NamedQuery(updateQuery(), status)
 	if err != nil {
 		if pqErr, ok := err.(*pq.Error); ok {
 			err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
@@ -190,12 +176,7 @@ func (status *TOStatus) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.Ap
 			return fmt.Errorf("this update affected too many rows: %d", rowsAffected), tc.SystemError
 		}
 	}
-	err = tx.Commit()
-	if err != nil {
-		log.Errorln("Could not commit transaction: ", err)
-		return tc.DBError, tc.SystemError
-	}
-	rollbackTransaction = false
+
 	return nil, tc.NoError
 }
 
@@ -206,24 +187,8 @@ func (status *TOStatus) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.Ap
 //generic error message returned
 //The insert sql returns the id and lastUpdated values of the newly inserted status and have
 //to be added to the struct
-func (status *TOStatus) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
-	rollbackTransaction := true
-	tx, err := db.Beginx()
-	defer func() {
-		if tx == nil || !rollbackTransaction {
-			return
-		}
-		err := tx.Rollback()
-		if err != nil {
-			log.Errorln(errors.New("rolling back transaction: " + err.Error()))
-		}
-	}()
-
-	if err != nil {
-		log.Error.Printf("could not begin transaction: %v", err)
-		return tc.DBError, tc.SystemError
-	}
-	resultRows, err := tx.NamedQuery(insertQuery(), status)
+func (status *TOStatus) Create() (error, tc.ApiErrorType) {
+	resultRows, err := status.ReqInfo.Tx.NamedQuery(insertQuery(), status)
 	if err != nil {
 		if pqErr, ok := err.(*pq.Error); ok {
 			err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
@@ -259,36 +224,15 @@ func (status *TOStatus) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.Ap
 	}
 	status.SetKeys(map[string]interface{}{"id": id})
 	status.LastUpdated = &lastUpdated
-	err = tx.Commit()
-	if err != nil {
-		log.Errorln("Could not commit transaction: ", err)
-		return tc.DBError, tc.SystemError
-	}
-	rollbackTransaction = false
+
 	return nil, tc.NoError
 }
 
 //The Status implementation of the Deleter interface
 //all implementations of Deleter should use transactions and return the proper errorType
-func (status *TOStatus) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
-	rollbackTransaction := true
-	tx, err := db.Beginx()
-	defer func() {
-		if tx == nil || !rollbackTransaction {
-			return
-		}
-		err := tx.Rollback()
-		if err != nil {
-			log.Errorln(errors.New("rolling back transaction: " + err.Error()))
-		}
-	}()
-
-	if err != nil {
-		log.Error.Printf("could not begin transaction: %v", err)
-		return tc.DBError, tc.SystemError
-	}
+func (status *TOStatus) Delete() (error, tc.ApiErrorType) {
 	log.Debugf("about to run exec query: %s with status: %++v", deleteQuery(), status)
-	result, err := tx.NamedExec(deleteQuery(), status)
+	result, err := status.ReqInfo.Tx.NamedExec(deleteQuery(), status)
 	if err != nil {
 		log.Errorf("received error: %++v from delete execution", err)
 		return tc.DBError, tc.SystemError
@@ -304,12 +248,7 @@ func (status *TOStatus) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.Ap
 			return fmt.Errorf("this create affected too many rows: %d", rowsAffected), tc.SystemError
 		}
 	}
-	err = tx.Commit()
-	if err != nil {
-		log.Errorln("Could not commit transaction: ", err)
-		return tc.DBError, tc.SystemError
-	}
-	rollbackTransaction = false
+
 	return nil, tc.NoError
 }
 
diff --git a/traffic_ops/traffic_ops_golang/status/statuses_test.go b/traffic_ops/traffic_ops_golang/status/statuses_test.go
index 3127450..7a684f1 100644
--- a/traffic_ops/traffic_ops_golang/status/statuses_test.go
+++ b/traffic_ops/traffic_ops_golang/status/statuses_test.go
@@ -24,8 +24,8 @@ import (
 	"time"
 
 	"github.com/apache/trafficcontrol/lib/go-tc"
+	"github.com/apache/trafficcontrol/lib/go-util"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
-	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/auth"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/test"
 	"github.com/jmoiron/sqlx"
 
@@ -60,8 +60,6 @@ func TestReadStatuses(t *testing.T) {
 	db := sqlx.NewDb(mockDB, "sqlmock")
 	defer db.Close()
 
-	refType := GetRefType()
-
 	testStatuses := getTestStatuses()
 	cols := test.ColsFromStructByTag("db", tc.Status{})
 	rows := sqlmock.NewRows(cols)
@@ -74,10 +72,14 @@ func TestReadStatuses(t *testing.T) {
 			ts.Name,
 		)
 	}
+	mock.ExpectBegin()
 	mock.ExpectQuery("SELECT").WillReturnRows(rows)
+	mock.ExpectCommit()
 	v := map[string]string{"dsId": "1"}
 
-	statuses, errs, _ := refType.Read(db, v, auth.CurrentUser{})
+	reqInfo := api.APIInfo{Tx:db.MustBegin(),CommitTx:util.BoolPtr(false)}
+
+	statuses, errs, _ := GetTypeSingleton()(&reqInfo).Read(v)
 	if len(errs) > 0 {
 		t.Errorf("status.Read expected: no errors, actual: %v", errs)
 	}
diff --git a/traffic_ops/traffic_ops_golang/types/types.go b/traffic_ops/traffic_ops_golang/types/types.go
index 7baaf52..f160f8b 100644
--- a/traffic_ops/traffic_ops_golang/types/types.go
+++ b/traffic_ops/traffic_ops_golang/types/types.go
@@ -28,7 +28,6 @@ import (
 	"github.com/apache/trafficcontrol/lib/go-tc"
 	"github.com/apache/trafficcontrol/lib/go-tc/tovalidate"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
-	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/auth"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/dbhelpers"
 
 	validation "github.com/go-ozzo/ozzo-validation"
@@ -37,13 +36,16 @@ import (
 )
 
 //we need a type alias to define functions on
-type TOType tc.TypeNullable
-
-//the refType is passed into the handlers where a copy of its type is used to decode the json.
-var refType = TOType(tc.TypeNullable{})
+type TOType struct{
+	ReqInfo *api.APIInfo `json:"-"`
+	tc.TypeNullable
+}
 
-func GetRefType() *TOType {
-	return &refType
+func GetTypeSingleton() func(reqInfo *api.APIInfo)api.CRUDer {
+	return func(reqInfo *api.APIInfo)api.CRUDer {
+		toReturn := TOType{reqInfo, tc.TypeNullable{}}
+		return &toReturn
+	}
 }
 
 func (typ TOType) GetKeyFieldsInfo() []api.KeyFieldInfo {
@@ -77,7 +79,7 @@ func (typ *TOType) GetType() string {
 	return "type"
 }
 
-func (typ *TOType) Validate(db *sqlx.DB) []error {
+func (typ *TOType) Validate() []error {
 	errs := validation.Errors{
 		"name":         validation.Validate(typ.Name, validation.Required),
 		"description":  validation.Validate(typ.Description, validation.Required),
@@ -89,7 +91,7 @@ func (typ *TOType) Validate(db *sqlx.DB) []error {
 	return nil
 }
 
-func (typ *TOType) Read(db *sqlx.DB, parameters map[string]string, user auth.CurrentUser) ([]interface{}, []error, tc.ApiErrorType) {
+func (typ *TOType) Read(parameters map[string]string) ([]interface{}, []error, tc.ApiErrorType) {
 	var rows *sqlx.Rows
 
 	// Query Parameters to Database Query column mappings
@@ -107,7 +109,7 @@ func (typ *TOType) Read(db *sqlx.DB, parameters map[string]string, user auth.Cur
 	query := selectQuery() + where + orderBy
 	log.Debugln("Query is ", query)
 
-	rows, err := db.NamedQuery(query, queryValues)
+	rows, err := typ.ReqInfo.Tx.NamedQuery(query, queryValues)
 	if err != nil {
 		log.Errorf("Error querying Types: %v", err)
 		return nil, []error{tc.DBError}, tc.SystemError
@@ -145,25 +147,9 @@ FROM type typ`
 //ParsePQUniqueConstraintError is used to determine if a type with conflicting values exists
 //if so, it will return an errorType of DataConflict and the type should be appended to the
 //generic error message returned
-func (typ *TOType) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
-	rollbackTransaction := true
-	tx, err := db.Beginx()
-	defer func() {
-		if tx == nil || !rollbackTransaction {
-			return
-		}
-		err := tx.Rollback()
-		if err != nil {
-			log.Errorln(errors.New("rolling back transaction: " + err.Error()))
-		}
-	}()
-
-	if err != nil {
-		log.Error.Printf("could not begin transaction: %v", err)
-		return tc.DBError, tc.SystemError
-	}
+func (typ *TOType) Update() (error, tc.ApiErrorType) {
 	log.Debugf("about to run exec query: %s with type: %++v", updateQuery(), typ)
-	resultRows, err := tx.NamedQuery(updateQuery(), typ)
+	resultRows, err := typ.ReqInfo.Tx.NamedQuery(updateQuery(), typ)
 	if err != nil {
 		if pqErr, ok := err.(*pq.Error); ok {
 			err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
@@ -194,12 +180,7 @@ func (typ *TOType) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErro
 		}
 		return fmt.Errorf("this update affected too many rows: %d", rowsAffected), tc.SystemError
 	}
-	err = tx.Commit()
-	if err != nil {
-		log.Errorln("Could not commit transaction: ", err)
-		return tc.DBError, tc.SystemError
-	}
-	rollbackTransaction = false
+
 	return nil, tc.NoError
 }
 
@@ -210,24 +191,8 @@ func (typ *TOType) Update(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErro
 //generic error message returned
 //The insert sql returns the id and lastUpdated values of the newly inserted type and have
 //to be added to the struct
-func (typ *TOType) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
-	rollbackTransaction := true
-	tx, err := db.Beginx()
-	defer func() {
-		if tx == nil || !rollbackTransaction {
-			return
-		}
-		err := tx.Rollback()
-		if err != nil {
-			log.Errorln(errors.New("rolling back transaction: " + err.Error()))
-		}
-	}()
-
-	if err != nil {
-		log.Error.Printf("could not begin transaction: %v", err)
-		return tc.DBError, tc.SystemError
-	}
-	resultRows, err := tx.NamedQuery(insertQuery(), typ)
+func (typ *TOType) Create() (error, tc.ApiErrorType) {
+	resultRows, err := typ.ReqInfo.Tx.NamedQuery(insertQuery(), typ)
 	if err != nil {
 		if pqErr, ok := err.(*pq.Error); ok {
 			err, eType := dbhelpers.ParsePQUniqueConstraintError(pqErr)
@@ -264,36 +229,15 @@ func (typ *TOType) Create(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErro
 
 	typ.SetKeys(map[string]interface{}{"id": id})
 	typ.LastUpdated = &lastUpdated
-	err = tx.Commit()
-	if err != nil {
-		log.Errorln("Could not commit transaction: ", err)
-		return tc.DBError, tc.SystemError
-	}
-	rollbackTransaction = false
+
 	return nil, tc.NoError
 }
 
 //The Type implementation of the Deleter interface
 //all implementations of Deleter should use transactions and return the proper errorType
-func (typ *TOType) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErrorType) {
-	rollbackTransaction := true
-	tx, err := db.Beginx()
-	defer func() {
-		if tx == nil || !rollbackTransaction {
-			return
-		}
-		err := tx.Rollback()
-		if err != nil {
-			log.Errorln(errors.New("rolling back transaction: " + err.Error()))
-		}
-	}()
-
-	if err != nil {
-		log.Error.Printf("could not begin transaction: %v", err)
-		return tc.DBError, tc.SystemError
-	}
+func (typ *TOType) Delete() (error, tc.ApiErrorType) {
 	log.Debugf("about to run exec query: %s with type: %++v", deleteQuery(), typ)
-	result, err := tx.NamedExec(deleteQuery(), typ)
+	result, err := typ.ReqInfo.Tx.NamedExec(deleteQuery(), typ)
 	if err != nil {
 		log.Errorf("received error: %++v from delete execution", err)
 		return tc.DBError, tc.SystemError
@@ -309,12 +253,6 @@ func (typ *TOType) Delete(db *sqlx.DB, user auth.CurrentUser) (error, tc.ApiErro
 		return fmt.Errorf("this create affected too many rows: %d", rowsAffected), tc.SystemError
 	}
 
-	err = tx.Commit()
-	if err != nil {
-		log.Errorln("Could not commit transaction: ", err)
-		return tc.DBError, tc.SystemError
-	}
-	rollbackTransaction = false
 	return nil, tc.NoError
 }
 
diff --git a/traffic_ops/traffic_ops_golang/types/types_test.go b/traffic_ops/traffic_ops_golang/types/types_test.go
index f69d5fe..252bed2 100644
--- a/traffic_ops/traffic_ops_golang/types/types_test.go
+++ b/traffic_ops/traffic_ops_golang/types/types_test.go
@@ -26,8 +26,8 @@ import (
 	"time"
 
 	"github.com/apache/trafficcontrol/lib/go-tc"
+	"github.com/apache/trafficcontrol/lib/go-util"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/api"
-	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/auth"
 	"github.com/apache/trafficcontrol/traffic_ops/traffic_ops_golang/test"
 	"github.com/jmoiron/sqlx"
 
@@ -81,10 +81,15 @@ func TestGetType(t *testing.T) {
 			ts.UseInTable,
 		)
 	}
+	mock.ExpectBegin()
 	mock.ExpectQuery("SELECT").WillReturnRows(rows)
+	mock.ExpectCommit()
 	v := map[string]string{"dsId": "1"}
 
-	types, errs, _ := refType.Read(db, v, auth.CurrentUser{})
+	reqInfo := api.APIInfo{Tx:db.MustBegin(),CommitTx:util.BoolPtr(false)}
+
+
+	types, errs, _ := GetTypeSingleton()(&reqInfo).Read(v)
 	if len(errs) > 0 {
 		t.Errorf("type.Read expected: no errors, actual: %v", errs)
 	}
@@ -118,7 +123,7 @@ func TestInterfaces(t *testing.T) {
 
 func TestValidate(t *testing.T) {
 	p := TOType{}
-	errs := test.SortErrors(p.Validate(nil))
+	errs := test.SortErrors(p.Validate())
 	expected := test.SortErrors([]error{
 		errors.New("'name' cannot be blank"),
 		errors.New("'description' cannot be blank"),