在Golang中的数据库事务处理

huangapple go评论76阅读模式
英文:

db transaction in golang

问题

在Java中,很容易在数据库事务的自动提交和手动提交之间进行切换。当我说容易时,我的意思是不需要更改连接接口。只需将setAutoCommit设置为true或false即可在自动/手动模式之间切换事务。然而,Go使用不同的连接接口,自动模式下使用sql.DB,手动模式下使用sql.Tx。对于一次性使用来说,这不是个问题。问题是我有一个使用sql.DB来处理数据库工作的框架,现在我想让其中一些加入我的新事务,但似乎没有那么容易,而不修改现有框架以接受sql.Tx。我想知道在Go中是否真的没有一种简单的方法来进行自动/手动切换?

英文:

In Java, it's pretty easy to switch between auto commit and manual commit of a database transaction. When I say easy, I mean it doesn't need to change the connection interface. Simply setAutoCommit to be true or false will switch the transaction between auto/manual mode. However, Go uses different connection interface, sql.DB for auto mode, and sql.Tx for manual mode. It's not a problem for a one off use. The problem is I have a framework which uses sql.DB to do the db work, now I want some of them to join my new transaction, and it seems to be not that easy without modifying the existing framework to accept sql.Tx. I am wondering if there is really not an easy way to do the auto/manual switch in Go?

答案1

得分: 6

在不了解你使用的框架的更多信息之前,我认为没有办法在不修改框架的情况下实现这一功能。你应该尽量将你所做的修改包含在框架中,因为这里的主要问题是你使用的框架设计得不好。当编写新语言的代码时(尤其是库或框架),你应该了解惯例并相应地设计你的软件。

在Go语言中,实现这个功能并不难,你只需要像这样声明Queryer(或者你想叫它的其他名字)接口:

type Queryer interface {
    Query(string, ...interface{}) (*sql.Rows, error)
    QueryRow(string, ...interface{}) *sql.Row
    Prepare(string) (*sql.Stmt, error)
    Exec(string, ...interface{}) (sql.Result, error)
}

这个接口会被sql.DBsql.Tx隐式地实现,所以在声明之后,你只需要修改函数/方法来接受Queryer类型而不是sql.DB类型。

英文:

Without knowing more about which framework you are using, I don't think there is a way to do it without modifying the framework. You should really try to get the modifications you do included in the framework because the main problem here is that the framework you are using is designed poorly. When writing for a new language (specially a library or framework) you should get to know the conventions and design your software accordingly.

In go, it is not to hard to accomplish this functionality you just have to declared the Queryer (or however you want to call it) interface like this:

type Queryer interface {
	Query(string, ...interface{}) (*sql.Rows, error)
	QueryRow(string, ...interface{}) *sql.Row
	Prepare(string) (*sql.Stmt, error)
	Exec(string, ...interface{}) (sql.Result, error)
}

This interface is implemented implicitly by the sql.DB and the sql.Tx so after declaring it, you just have to modify the functions/methods to accept the Queryer type instead of a sql.DB.

huangapple
  • 本文由 发表于 2014年10月28日 01:59:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/26593867.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定