golang db事务的统一封装的实现
作者:yuchenfw 发布时间:2023-07-02 21:01:51
标签:golang,db,事务,封装
事务处理的流程示例
database := db.DB
tx, err := database.Begin()
if err != nil {
return err
}
stmt, err := tx.Prepare(sqlQuery)
if err != nil {
tx.Rollback()
return err
}
_, err = stmt.Exec(paras...)
if err != nil {
tx.Rollback()
return err
}
err = tx.Commit()
if err != nil {
tx.Rollback()
return err
}
以上是我们使用事务时的一般操作,如果每做一次事务的操作均要进行重新写一遍代码岂不是很麻烦,尤其是出错时,Rollback需要多次在不同错误的地方的进行调用处理。
简单封装
偷懒第一步
采用defer处理Rollback
defer tx.Rollback()
无论成功与否,均进行Rollback操作,只是有点影响,如果成功还调用Rollback的话,将会报错。虽然可以忽略,但作为程序员,有必要进一步调整。
偷懒第二步
根据执行结果来选择执行Rollback,避免无效使用。
defer func() { //根据执行结果选择执行Rollback
if err != nil && tx != nil {
log.Println("ExecSqlWithTransaction defer err :", err)
tx.Rollback()
}
}()
如此,我们就可以根据事务的执行结果决定是否Rollback了。
偷懒第三步
封装,以上代码本身就具有极大的普适性,因此,我们抽出通用的参数,将此过程封装成一个func,以后就可以直接调用了。
func ExecSqlWithTransaction(database *sql.DB, query string, args ...interface{}) (err error) {
tx, err := database.Begin()
if err != nil {
return err
}
defer func() {
if err != nil && tx != nil {
tx.Rollback()
}
}()
stmt, err := tx.Prepare(query)
if err != nil {
return err
}
defer stmt.Close()
_, err = stmt.Exec(args...)
if err != nil {
return err
}
return tx.Commit()
}
封装后我们可以如下使用:
if err := ExecSqlWithTransaction(database,sqlQuery,paras...);err != nil{
//错误处理
}
封装后是不是很简洁啊?
进一步封装
在一个事务中可能会出现多个SELECT、UPDATE等操作,以上封装仅处理了一种操作,还不能满足我们的实际需求,因此需要更进一步封装。
func ExecSqlWithTransaction(db *sql.DB, handle func(tx *sql.Tx) error) (err error) {
tx, err := db.Begin()
if err != nil {
return err
}
defer func() {
if err != nil {
tx.Rollback()
}
}()
if err = handle(tx); err != nil {
return err
}
return tx.Commit()
}
在handle func内可以直接使用事务tx进行增删改查。
来源:https://blog.csdn.net/xz_studying/article/details/90610993


猜你喜欢
- pytorch 输出中间层特征:tensorflow输出中间特征,2种方式:1. 保存全部模型(包括结构)时,需要之前先add_to_col
- Python中赋值的含义在C++中,变量就是对象本身,对变量赋值就改变了它代表的对象。而在Python中,赋值的含义却是关联变量名字和实际对
- 如果是导入有中文的数据,我的mysql 设置的utf8 字符集,所以你要导入的xxx.txt 文件也要保存ut
- 概述从今天开始我们将开启一段自然语言处理 (NLP) 的旅程. 自然语言处理可以让来处理, 理解, 以及运用人类的语言, 实现机器语言和人类
- 日志中也没有打印什么明显的错误,只是显示连接了rabbitmq后就关闭了[2019-09-11 06:08:45,729: INFO/Bea
- 使用正则表达式的几个步骤:1、用import re 导入正则表达式模块;2、用re.compile()函数创建一个Regex对象;3、用Re
- 文件结构html_downloader.py - 下载网页html内容#!/usr/bin/python# -*- coding: UTF-
- 1. 问题使用PyCharm 创建完Django 项目 想登录admin 页面 却不知道用户名和密码。 用的默认sqlit2.解决办法2.1
- 编者按,网站中让人惊喜的往往是那一点细节,只要用心留意你将发现那些美好的用户体验就在身边。新蛋网想自主控制链接在原窗口还是新窗口中打开?看看
- 1. 哈希算法基础1.1 哈希算法的定义哈希算法(Hash Algorithm)是一种将任意长度的输入数据映射为固定长度哈希值的算法。它具有
- 目录MySQL数据库重命名的方法 第一种方法:rename database 弃用了第二种方法:mysqldump 备份第三种方法
- 安装laravel框架命令行cd进入指定目录下,执行composer create-project --prefer-dist larave
- Python + opencv 读取视频的三种情况:情况一:通过摄像头采集视频情况二:通过本地视频文件获取视频情况三:通过摄像头录制视频,再
- 本文实例为大家分享了微信小程序实现简单倒计时的具体代码,供大家参考,具体内容如下任务描述:计时器任务要求:案例描述:设计一个实现倒计时功能的
- 一、定义(1)如果一个问题的规模是n,解这一问题的某一算法所需要的时间为T(n),它是n的某一函数 T(n)称为这一算法的“时间复杂性”。我
- 本文实例为大家分享了python交互式图形编程实例的第三部代码,供大家参考,具体内容如下#!/usr/bin/env python3# -*
- SQL 多条件查询以后我们做多条件查询,一种是排列结合,另一种是动态拼接SQL如:我们要有两个条件,一个日期@addDate,一个是@nam
- ASP中给函数传参确实是个麻烦事,当参数个数特别多的时候(比如有七八个或者更多的参数个数)差不多就要眼冒金星了,一个个的数吧。而且要命的是参
- 一、ASP的平反想到ASP 很多人会说 “asp语言很蛋疼,不能面向对象,功能单一,很多东西实现不了” 等等诸如此类。 以上说法都是错误的,
- Tag,直译标签,是一种由用户自定义的、用于描述信息 [1]的关键词。Tagging是用户为信息赋予Tag的行为。Delicious,Fli