在前文介绍访问数据库时介绍了github.com/jmoiron/sqlx包,本文基于这个包使用数据库事务。

defer

在使用数据库事务之前,首先需要了解go语言的defer关键字。defer是go语言的延迟执行语句,defer后面的语句会被go进行延迟处理,在函数即将结束的时候,defer后面的语句将逆序执行。也就是说,先defer的语句最后执行。defer很像java或者C#中的finally语句。下面通过一个例子看一下defer。

package main

import "fmt"

func main() {
fmt.Println("defer 开始")
defer fmt.Println(1)
defer fmt.Println(2)
defer fmt.Println(3)
panic("测试 panic")
fmt.Println("defer 结束")
}

代码运行结果:

defer 开始
3
2
1
panic: 测试 panic goroutine 1 [running]:
main.main()
/tests/gookokok/main.go:10 +0x1b8 Process finished with exit code 2

通过运行结果可以看到defer的逆序输出。在之后又手动触发了一个panic,影响了最后一行的输出defer 结束,go在触发panic时优先执行了defer,足以证明defer是非常安全的,所以defer也常常被用来互斥解锁、关闭文件或数据库事务的处理。

事务

sqlx使用事务和database/sql相比扩展出了MustBegin()、MustExec()等方法,这样就不需要在代码中手动处理很多错误。MustBegin会在出现错误的时候触发panic而不是返回错误,这样就可以在代码的更上一层统一处理错误。

tx, err := db.Begin()
err = tx.Exec(...)
err = tx.Commit() tx := db.MustBegin()
tx.MustExec(...)
err = tx.Commit()

sqlx支持以上两种开启事务的方法。MustBegin返回sqlx.Tx,sqlx.Tx也提供了Select,Get之类的API,执行数据库操作和使用sqlx.DB是一样的。

以上代码执行tx.MustExec(...)如果报错的话,代码将没有机会运行到tx.Commit(),这样数据库连接会等到go进行垃圾回收的时候才能关闭,而且很高并发的话,可能会占满数据库连接数,造成站点无法访问的情况。

tx := db.MustBegin()
defer tx.Rollback()
tx.MustExec(...)
err = tx.Commit()

代码中加入defer tx.Rollback()就可以解决问题。通过前面的介绍已知defer是在方法即将结束时执行,哪怕是代码出现异常也不会影响数据库连接。

文章出处:基于gin的golang web开发:使用数据库事务

基于gin的golang web开发:使用数据库事务的更多相关文章

  1. 基于gin的golang web开发:访问mysql数据库

    web开发基本都离不开访问数据库,在Gin中使用mysql数据库需要依赖mysql的驱动.直接使用驱动提供的API就要写很多样板代码.你可以找到很多扩展包这里介绍的是jmoiron/sqlx.另外还有 ...

  2. 基于gin的golang web开发:mysql增删改查

    Go语言访问mysql数据库需要用到标准库database/sql和mysql的驱动.标准库的Api使用比较繁琐这里再引入另一个库github.com/jmoiron/sqlx. go get git ...

  3. 基于gin的golang web开发:路由

    Gin是一个用Golang编写的HTTP网络框架.它的特点是类似于Martini的API,性能更好.在golang web开发领域是一个非常热门的web框架. 启动一个Gin web服务器 使用下面的 ...

  4. 基于gin的golang web开发:路由二

    在基于gin的golang web开发:路由中我们介绍了Gin的路由和一些获取链接中参数的方法,本文继续介绍其他获取参数的方法. 文件上传 在web开发中文件上传是一个很常见的需求,下面我们来看一下基 ...

  5. 基于gin的golang web开发:模型绑定

    在前两篇文章介绍路由的时候,我们了解到gin可用通过类似DefaultQuery或DefaultPostForm等方法获取到前端提交过来的参数.参数不多的情况下也很好用,但是想想看,如果接口有很多个参 ...

  6. 基于gin的golang web开发:模型验证

    Gin除了模型绑定还提供了模型验证功能.你可以给字段指定特定的规则标签,如果一个字段用binding:"required"标签修饰,在绑定时该字段的值为空,那么将返回一个错误.开发 ...

  7. 基于gin的golang web开发:中间件

    gin中间件(middleware)提供了类似于面向切面编程或路由拦截器的功能,可以在请求前和请求之后添加一些自定义逻辑.实际开发中有很多场景会用到中间件,例如:权限验证,缓存,错误处理,日志,事务等 ...

  8. 基于gin的golang web开发:集成swagger

    在前后端分离的项目维护一份完整且及时更新的api文档会极大的提高我们的工作效率,传统项目中接口文档都是由后端开发手写的,这种文档很难保证及时性,久而久之便失去了参考意义.swagger给我们提供了一种 ...

  9. 基于gin的golang web开发:永远不要相信用户的输入

    作为后端开发者我们要记住一句话:"永远不要相信用户的输入",这里所说的用户可能是人,也可能是另一个应用程序."永远不要相信用户的输入"是安全编码的准则,也就是说 ...

随机推荐

  1. 怎么写一个Activity

    a.新建一个类继承Actitvity b.重写oncreate方法 setContentView(R.layout.XXX);//设置布局文件 c.注册activity <activity an ...

  2. Jmeter之『多变量循环』

    假设存在两个参数a,b,需要在一个循环内,同时遍历a_1,a_2,a_3,b_1,b_2,b_3 添加一个循环控制器,循环次数为变量的大小 添加一个计数器,引用名称为index(用于拼接变量名称) 同 ...

  3. Ubuntu通过Apache安装WebDav

    使用KeePass保存密码,在个人服务器上安装WebDav协议. # 安装Apache2服务器 sudo aptitude install -y apache2 # 开启Apache2中对WebDav ...

  4. 二进制K8S集群使用Bootstrap Token 方式增加Node

    TLS Bootstraping:在kubernetes集群中,Node上组件kebelet和kube-proxy都需要与kube-apiserver进行通信,为了增加传输安全性,采用https方式, ...

  5. devops-jenkins-Pipeline实战

    1) 配置gitlab的分支项目 点击红色标记的创建 project 项目 点击Create project创建Pipeline-demo项目 项目创建完成,然后我们创建一个Add README 然后 ...

  6. RFC 8684---TCP Extensions for Multipath Operation with Multiple Addresses

    https://datatracker.ietf.org/doc/rfc8684/?include_text=1 TCP Extensions for Multipath Operation with ...

  7. c# 误区系列(一)

    前言 整理很早以前认为的一些误区,准备整理一个系列.新手可以看下,然后大佬指点一下是否哪些地方错了. 正文 值类型存在栈上,引用类型存在堆上 很多人认为用这句话来解释值类型和栈类型的区别,甚至有些文章 ...

  8. 正式班D9

    2020.10.16星期五 正式班D9 一.vmware workstation的使用 虚拟机管理软件 定义 虚拟机(Virtual Machine)软件是一套特殊的软件,它可以作为操作系统独立运行, ...

  9. Termux基础教程(一):技能部署

    Termux基础教程 by CUCI Termux 是一个 Android 下一个高级的终端模拟器,开源且不需要 root,支持 apt 管理软件包,十分方便安装软件包,完美支持 Python. PH ...

  10. go xpath

    package main import ( "fmt" "github.com/antchfx/htmlquery" "net/http" ...