匿名函数与gorm中的Transaction事务方法

整理下go中的匿名函数,项目中很多地方都在用。

1、函数类型的变量

Go中,函数也是一种数据类型。定义一个函数,把这个函数赋值给一个变量,这个变量就是函数类型的变量,用这个变量等价于直接调函数

package mainimport "fmt"//定义一个函数:
func test(num int){fmt.Println(num)
}func main(){//函数也是一种数据类型,可以赋值给一个变量	a := test	//a变量就是一个函数类型的变量fmt.Printf("a的类型是:%T,test函数的类型是:%T \n",a,test)	//a的类型是:func(int),test函数的类型是:func(int)//通过该变量可以对函数调用a(10) //等价于  test(10)
}

在这里插入图片描述

2、函数类型的形参

有函数类型的变量,那函数类型的形参也可以。对于函数类型的形参,可以选择传入类型相同的函数名称或者变量,也可以用匿名函数直接写逻辑

package mainimport "fmt"//定义一个函数
func test(num int){fmt.Println(num)
}//定义一个函数,把另一个函数作为形参
func test02 (num1 int ,num2 float32, fc func(int)){fc(num1)	//调用形参对应的函数
}func main(){//a变量就是一个函数类型的变量a := test//传入类型相同的函数名称test02(1, 3.14, test)//传入类型相同的函数类型的变量test02(2, 3.14, a)//传入一个匿名函数test02(3, 3.14, func(num int) {fmt.Println(num)})}

在这里插入图片描述

3、gorm中的Transaction方法

gorm框架中的Transaction方法,形参是一个函数类型func(tx *gorm.DB) error,下面直接用匿名函数给Transaction方法传参,匿名函数中自然是拿gorm.DB对象去做一系列的insert操作

// 使用事务执行数据库操作
err := db.Transaction(func(tx *gorm.DB) error {// 在事务中执行一系列数据库操作if err := tx.Model(&User{}).Create(&User{Name: "John"}).Error; err != nil {// 如果其中一个操作失败,则回滚事务return err}if err := tx.Model(&Order{}).Create(&Order{UserID: 1, Product: "Phone"}).Error; err != nil {// 如果其中一个操作失败,则回滚事务return err}// 如果所有操作都成功,则提交事务return nil
})if err != nil {// 处理事务执行过程中的错误log.Println("Transaction failed:", err)
}

db.Transaction 方法开启了一个数据库事务,在事务中,依次执行了两个数据库操作:创建一个新用户和创建一个新订单。如果其中一个操作失败,则事务会回滚,所有之前的操作都会被撤销。如果所有操作都成功,则事务会被提交。

以上写法基本固定,有一步Create失败,然会error,事务回滚,执行到最后,说明前面的一个个Create都成功,return nil,提交事务。

4、Transaction方法源码

// Transaction start a transaction as a block, return error will rollback, otherwise to commit. Transaction executes an
// arbitrary number of commands in fc within a transaction. On success the changes are committed; if an error occurs
// they are rolled back.
func (db *DB) Transaction(fc func(tx *DB) error, opts ...*sql.TxOptions) (err error) {//声明一个变量 panicked,用于标记是否发生了 panicpanicked := true//检查当前数据库连接池是否实现了 TxCommitter 接口,并且该接口不为 nil。//如果满足条件,说明支持嵌套事务,可以使用保存点进行处理if committer, ok := db.Statement.ConnPool.(TxCommitter); ok && committer != nil {// nested transaction(嵌套事务)//检查是否禁用了嵌套事务。如果未禁用,将创建保存点来实现嵌套事务if !db.DisableNestedTransaction {//创建一个保存点,命名为函数指针的字符串表示形式,并将错误赋给变量 errerr = db.SavePoint(fmt.Sprintf("sp%p", fc)).Errorif err != nil {return}defer func() {// 善后处理,如果发生了 panic 或者函数执行过程中出现了错误,将回滚到之前创建的保存点if panicked || err != nil {db.RollbackTo(fmt.Sprintf("sp%p", fc))}}()}//调用传入的函数 fc,并将一个新的 Session 对象作为参数传递给它//Session 对象会创建一个新的数据库连接,如果 db.clone 的值为 1,则表示创建一个新的数据库连接//数据库连接对象传入给函数类型的变量fc//我上面写的匿名函数就被调用//开始执行我的一些列Create方法//执行完成后,把错误赋给err变量//err不为空,自会被defer中的匿名函数回滚err = fc(db.Session(&Session{NewDB: db.clone == 1}))//当前数据库连接池不支持嵌套事务,或者嵌套事务被禁用} else {//开始一个新的数据库事务,并将返回的事务赋给变量 txtx := db.Begin(opts...)if tx.Error != nil {return tx.Error}defer func() {// 同样的defer搭配匿名函数,有一步err就回滚if panicked || err != nil {tx.Rollback()}}()//函数类型的变量fx,调用我传入的匿名函数,进行一系列Createif err = fc(tx); err == nil {//没发生错误,改标志位为falsepanicked = false//事务提交return tx.Commit().Error}}panicked = falsereturn
}

上面源码中也体现了匿名函数的另一个用途:搭配defer

defer func() {// Make sure to rollback when panic, Block error or Commit errorif panicked || err != nil {db.RollbackTo(fmt.Sprintf("sp%p", fc))}
}()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/958.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数字阅览室解决方案

一、方案概述 “数字阅览室”概念一经提出,就得到了广泛的关注,纷纷组织力量进行探讨、研究和开发,进行各种模型的试验。随着数字地球概念、技术、应用领域的发展,数字阅览室已成为数字地球家庭的成员,为信息高速公路…

高频前端面试题汇总之JavaScript篇(上)

一、数据类型 1. JavaScript有哪些数据类型,它们的区别? JavaScript共有八种数据类型,分别是 Undefined、Null、Boolean、Number、String、Object、Symbol、BigInt。 其中 Symbol 和 BigInt 是ES6 中新增的数据类型: Symbol 代…

如何免费申请长期HTTPS证书?

长期HTTPS证书申请步骤: 第一步:确定证书类型 根据你的网站需求,选一种适合的HTTPS证书。一般有这几种: - 域名型(DV)证书:最基础,验证你对域名的所有权,适合个人网站或…

构建有序链表,有序链表的归并,反转链表

本次将对于构建有序链表,有序链表的归并,反转链表,进行一一介绍和代码分享。 首先是一些链表中的基本的函数: Node* creatList() {Node* headNode (Node*)malloc(sizeof(Node));assert(headNode);headNode->next NULL;retu…

海信电视:中国游戏的影像“黑神话”

【潮汐商业评论/文】 《西游记》最后一难中,通天河老鼋回唐三藏“何时才能修成正果”,《黑神话:悟空》也曾面临这个拷问,如今海信电视与它正在共同回答这个命题。 自2020年发布预告片震动行业后,这部游戏就承载着太多…

Shader 渐变屏幕

渐变 前置工作,创建缓冲,对顶点着色器传递顶点数据 function main() {var canvas document.getElementById(webgl);var gl getWebGLContext(canvas);if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) returnvar n initVertexBuffers(gl); }fu…

HBM 发展史与前景(持续更新)

主页: 元存储博客 文章目录 前言1. JEDEC 规范2. HBM 发展历程3. HBM 应用场景4. HBM 市场前景5. 发展挑战 翻译自: https://namu.wiki/w/HBM 前言 NVIDIA H2 上的 HBM100e。 1. JEDEC 规范 2. HBM 发展历程 HBM技术曾被视为一种噱头,因为它…

PSAvatar:一种基于点的可变形形状模型,用于3D高斯溅射的实时头部化身创建

PSAvatar: A Point-based Morphable Shape Model for Real-Time Head Avatar Creation with 3D Gaussian Splatting PSAvatar:一种基于点的可变形形状模型,用于3D高斯溅射的实时头部化身创建 Zhongyuan Zhao1,2, Zhenyu Bao1,2, Qing Li1, Guoping Qiu3,…

工时管理软件全攻略,8大关键因素一网打尽!

工时管理往往与项目管理与人力资源结合起来,考察每位员工的绩效指标。可以说,工时管理软件至关重要。什么叫工时管理?考虑到工时管理软件的八个关键要素包含:功能、使用体验、集成能力、扩展性、成本效率、安全隐私、技术支持、用…

javaWeb项目-智慧餐厅点餐管理系统功能介绍

项目关键技术 开发工具:IDEA 、Eclipse 编程语言: Java 数据库: MySQL5.7 框架:ssm、Springboot 前端:Vue、ElementUI 关键技术:springboot、SSM、vue、MYSQL、MAVEN 数据库工具:Navicat、SQLyog 1、JavaScript Java…

【漏洞复现】泛微e-cology ProcessOverRequestByXml接口存在任意文件读取漏洞

漏洞描述 泛微e-cology依托全新的设计理念,全新的管理思想。 为中大型组织创建全新的高效协同办公环境。 智能语音办公,简化软件操作界面。 身份认证、电子签名、电子签章、数据存证让合同全程数字化。泛微e-cology ProcessOverRequestByXml接口存在任意文件读取漏洞 免责声…

虚拟机磁盘剩余空间不足

VMware 弹出提示: 对文件“E:\Virtual Machine\CentOS 7 1810 的克隆 (2)\CentOS 7 1810-cl1.vmdk”的操作失败。 如果该文件位于远程文件系统上,请确保网络连接以及该磁盘所在的服务器正常工作。如果该文件位于可移动介质中,请重新连接该介…

从零自制docker-11-【pivotRoot切换实现文件系统隔离】

文章目录 busyboxdocker run -d busybox topcontainerId(docker ps --filter "ancestorbusybox:latest"|grep -v IMAGE|awk {print $1})docker export -o busybox.tar $containerId or sudo docker export 09bbf421d93f > ./busybox.tar tar -xvf busybox.tar -C …

nvm下载的node没有npm

nvm下载的node没有npm 相信大家最近可能发现自己使用的nvm下载nodejs没有npm了。 会出现这种情况: C:\Users\89121>nvm install 15 Downloading node.js version 15.14.0 (64-bit)... Complete Downloading npm version 7.7.6... Download failed. Rolling Bac…

如何查找一篇英文文献的源代码?(论文中没有源代码链接时)如何查找一篇论文的实现代码从而复现论文?

有两个网址,从这两个网址里面能找到论文相关代码,但不确定是不是人家论文里的源代码,但是根据论文实在找不到的情况下,只能试试这两个网址了 1. https://paperswithcode.com/ 2. https://www.catalyzex.com/

【QT进阶】Qt Web混合编程之CMake VS2019编译并使用QCefView(图文并茂超详细版本)

往期回顾 【QT进阶】Qt Web混合编程之CEF、QCefView简单介绍-CSDN博客 【QT进阶】Qt Web混合编程之VS2019 CEF的编译与使用(图文并茂超详细介绍)-CSDN博客【QT进阶】Qt Web混合编程之QWebEngineView基本用法-CSDN博客【QT进阶】Qt Web混合编程之VS2019 C…

Geoserver的RESTful接口使用

概述 GeoServer提供了一个RESTful接口,客户端可以通过该接口获取有关实例的信息并进行配置更改。REST接口使用简单的HTTP调用,通过客户端就可以配置GeoServer,而无需使用Web管理接口。 Geoserver中的关系 工作区、数据源、图层、图层组以及…

随身WiFi真实测评推荐!格行vs新讯随身wifi对比,公认最好的随身WiFi格行随身wifi有什么优势?

在当前移动网络高度发达的时代,随身 WiFi 已成为人们出差、旅行等场景中不可或缺的工具。格行和新讯是目前比较受欢迎的无线随身wifi。本次评测将对比分析这两款产品的区别,做为随身WiFi推荐第一名的格行随身wifi到底有什么优势呢? 品牌对比&…

手写Java设计模式之工厂模式,附源码解读

工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一,这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 工厂模式提供了一种创建对象的方式,而无需指定要创建的具体类。 工厂模式属于创建型…

网络流问题详解

1. 网络最大流 1.1 容量网络和网络最大流 1.1.1 容量网络 设 G(V, E)是一个有向网络,在 V 中指定了一个顶点,称为源点(记为 Vs),以及另一个顶点,称为汇点(记为 Vt);对…