ent 基本使用十九 事务处理
ent 生成的代码中client 提供了比较全的事务处理
启动单个事务进行处理
- // GenTx generates group of entities in a transaction.
- func GenTx(ctx context.Context, client *ent.Client) error {
- tx, err := client.Tx(ctx)
- if err != nil {
- return fmt.Errorf("starting a transaction: %v", err)
- }
- hub, err := tx.Group.
- Create().
- SetName("Github").
- Save(ctx)
- if err != nil {
- return rollback(tx, fmt.Errorf("failed creating the group: %v", err))
- }
- // Create the admin of the group.
- dan, err := tx.User.
- Create().
- SetAge(29).
- SetName("Dan").
- AddManage(hub).
- Save(ctx)
- if err != nil {
- return rollback(tx, err)
- }
- // Create user "Ariel".
- a8m, err := tx.User.
- Create().
- SetAge(30).
- SetName("Ariel").
- AddGroups(hub).
- AddFriends(dan).
- Save(ctx)
- if err != nil {
- return rollback(tx, err)
- }
- fmt.Println(a8m)
- // Output:
- // User(id=2, age=30, name=Ariel)
-
- // Commit the transaction.
- return tx.Commit()
- }
-
- // rollback calls to tx.Rollback and wraps the given error
- // with the rollback error if occurred.
- func rollback(tx *ent.Tx, err error) error {
- if rerr := tx.Rollback(); rerr != nil {
- err = fmt.Errorf("%v: %v", err, rerr)
- }
- return err
- }
事务client 封装
有时已经使用了 *ent.Client
但是我们需要支持事务,就可以使用次方法
- // WrapGen wraps the existing "Gen" function in a transaction.
- func WrapGen(ctx context.Context, client *ent.Client) error {
- tx, err := client.Tx(ctx)
- if err != nil {
- return err
- }
- txClient := tx.Client()
- // Use the "Gen" below, but give it the transactional client; no code changes to "Gen".
- if err := Gen(ctx, txClient); err != nil {
- return rollback(tx, err)
- }
- return tx.Commit()
- }
-
- // Gen generates a group of entities.
- func Gen(ctx context.Context, client *ent.Client) error {
- // ...
- return nil
- }
最佳实践
- 一个可重用的事务帮助方法
- func WithTx(ctx context.Context, client *ent.Client, fn func(tx *ent.Tx) error) error {
- tx, err := client.Tx(ctx)
- if err != nil {
- return err
- }
- defer func() {
- if v := recover(); v != nil {
- tx.Rollback()
- panic(v)
- }
- }()
- if err := fn(tx); err != nil {
- if rerr := tx.Rollback(); rerr != nil {
- err = errors.Wrapf(err, "rolling back transaction: %v", rerr)
- }
- return err
- }
- if err := tx.Commit(); err != nil {
- return errors.Wrapf(err, "committing transaction: %v", err)
- }
- return nil
- }
- 使用
- func Do(ctx context.Context, client *ent.Client) {
- // WithTx helper.
- if err := WithTx(ctx, client, func(tx *ent.Tx) error {
- return Gen(ctx, tx.Client())
- }); err != nil {
- log.Fatal(err)
- }
- }
参考资料
https://entgo.io/docs/transactions/
ent 基本使用十九 事务处理的更多相关文章
- COJ 0981 WZJ的数据结构(负十九)树综合
WZJ的数据结构(负十九) 难度级别:E: 运行时间限制:3500ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 WZJ的数据结构中有很多都是关于树的.这让很多练习 ...
- 智课雅思词汇---十九、前缀se是什么意思
智课雅思词汇---十九.前缀se是什么意思 一.总结 一句话总结:前缀:se- 表示“分开, 离开, 区别开” 前缀:se- [词根含义]:分离 [同源单词]:secede, secession, s ...
- 无废话ExtJs 入门教程十九[API的使用]
无废话ExtJs 入门教程十九[API的使用] extjs技术交流,欢迎加群(201926085) 首先解释什么是 API 来自百度百科的官方解释:API(Application Programmin ...
- Python之路【第十九章】:Django进阶
Django路由规则 1.基于正则的URL 在templates目录下创建index.html.detail.html文件 <!DOCTYPE html> <html lang=&q ...
- Bootstrap <基础二十九>面板(Panels)
Bootstrap 面板(Panels).面板组件用于把 DOM 组件插入到一个盒子中.创建一个基本的面板,只需要向 <div> 元素添加 class .panel 和 class .pa ...
- Bootstrap <基础十九>分页
Bootstrap 支持的分页特性.分页(Pagination),是一种无序列表,Bootstrap 像处理其他界面元素一样处理分页. 分页(Pagination) 下表列出了 Bootstrap 提 ...
- Web 开发人员和设计师必读文章推荐【系列二十九】
<Web 前端开发精华文章推荐>2014年第8期(总第29期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...
- Web 前端开发精华文章集锦(jQuery、HTML5、CSS3)【系列十九】
<Web 前端开发精华文章推荐>2013年第七期(总第十九期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各种增强网站用户体验的 jQuery 插件,展示前沿的 HTML5 和 C ...
- Python之路【第十九篇】:爬虫
Python之路[第十九篇]:爬虫 网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本.另外一些不常使用 ...
随机推荐
- HTML5 Canvas实战之刮奖效果【转】
开源项目地址:https://github.com/artwl/Lottery 作者博客地址:http://www.cnblogs.com/jscode/p/3580878.html 谢谢浏览!
- BZOJ3277 串(后缀自动机)
对多串建立SAM的一种方法是加分隔符.于是加完分隔符建出SAM. 考虑统计出每个节点被多少个串包含.让每个串各自在SAM上跑,跑到一个节点就标记(显然一定会完全匹配该节点,因为是对包含其的串建的SAM ...
- ping程序和tracert(traceroute)背后的故事--ICMP协议
为路由器生,为交换机死,为了Ping通奋斗一辈子-----tracert.cn 上面是一个网络工程师的个人定位,很有意思,哈哈!那么我们来看看ping和tracert都是什么吧 PING (Packe ...
- MOOC 数据库笔记(五):关系演算
关系演算 概述 (这部分的内容大多与离散数学有关,我没有相关基础,所以现在只是简单看一下) 关系演算是以数理逻辑中的谓词演算为基础的. 关系演算是描述关系运算的另一种思维方式. SQL语言是继承了关系 ...
- SUSE12Sp3-安装DockerCE和Docker-compose
最近在写脚本.发现还是很方便的. Docker下载地址:https://download.docker.com/linux/static/stable/x86_64/ 执行以下脚本即可安装完毕. #! ...
- Python基础之datetime、sys模块
1.datetime模块 1)datetime.datetime.now(),返回各当前时间.日期类型. datetime.datetime.now(),返回当前日期. import datetime ...
- JavaScript---正则使用,日期Date的使用,Math的使用,JS面向对象(工厂模式,元模型创建对象,Object添加方法)
JavaScript---正则使用,日期Date的使用,Math的使用,JS面向对象(工厂模式,元模型创建对象,Object添加方法) 一丶正则的用法 创建正则对象: 方式一: var reg=new ...
- Python列表,元组,字典,集合
列表 Python中列表是可变的,这是它区别于字符串和元组的最重要的特点,一句话概括即:列表可以修改,而字符串和元组不能. 列表追加数据的方法:append(),extend(数组),insert(位 ...
- Tensorflow快餐教程(1) - 30行代码搞定手写识别
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/lusing/article/details ...
- Django之ORM数据查询方式练习
单表查询 单表查询简单示例 # 字段 models.DateField(auto_now_add) models.DateField(auto_now) # auto_now 和auto_now_ad ...