On Thu, Dec 6, 2018 at 4:37 PM roger peppe <rogpe...@gmail.com> wrote:

> How would generics help you here? The WithTxn function is already generic
> (courtesy of closures) and there's no reason it couldn't be put in a
> publicly importable package somewhere.
>

When I use the equivalent functionality, I tie it to an interface
specifically for the database changes / queries allowed. Makes for great
separation between the database layer and the business logic. That means,
however, every time I have a new database API, there's a new interface, and
a new implementation of the function.

Eric.


> On Thu, 6 Dec 2018, 10:26 pm Eric Johnson <e...@tibco.com wrote:
>
>>
>>
>> On Thu, Dec 6, 2018 at 12:16 AM roger peppe <rogpe...@gmail.com> wrote:
>>
>>>
>>>
>>> On Wed, 5 Dec 2018 at 18:55, 'Eric Johnson' via golang-nuts <
>>> golang-nuts@googlegroups.com> wrote:
>>>
>>>> I always go with the approach that uses the equivalent of the
>>>> "Transact()" method.
>>>>
>>>> On top of that, rather than use a generic *sql.Tx parameter to the
>>>> "txFunc" function, I pass an interface that is specific to the operations
>>>> of the database layer for my application.
>>>>
>>>
>>> That's an interesting idea. For the record, this is the code we use:
>>>
>>
>> This is one of *the* places in my code where I'd probably immediately
>> take advantage of "generics" in Go. This function to wrap transactions
>> could be written generically, and then not have to be copied from
>> application to application. While I could go with the work-around to leave
>> the function in the *sql.Tx parameter form, the other approach is *so*
>> useful that I copy the function instead.
>>
>> Eric
>>
>>
>>>
>>>     package transaction
>>>
>>>     import (
>>>         "context"
>>>         "database/sql"
>>>         "fmt"
>>>
>>>         "gopkg.in/errgo.v1"
>>>     )
>>>
>>>     // WithTxn executes a function inside a transaction context.
>>>     func WithTxn(db *sql.DB, ctx context.Context, f func(*sql.Tx) error)
>>> error {
>>>         txn, err := db.BeginTx(ctx, nil)
>>>         if err != nil {
>>>             return errgo.Mask(err)
>>>         }
>>>         if err := f(txn); err != nil {
>>>             return rollback(txn, err)
>>>         }
>>>         return rollback(txn, txn.Commit())
>>>     }
>>>
>>>     func rollback(txn *sql.Tx, err error) error {
>>>         if err == nil {
>>>             return nil
>>>         }
>>>         errRollback := txn.Rollback()
>>>         if errRollback != nil {
>>>             return errgo.NoteMask(err, fmt.Sprintf("failed to roll back
>>> (error: %v) after", errRollback), errgo.Any)
>>>         }
>>>         return err
>>>     }
>>>
>>>>
>>>>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to