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 基本使用十九 事务处理的更多相关文章

  1. COJ 0981 WZJ的数据结构(负十九)树综合

    WZJ的数据结构(负十九) 难度级别:E: 运行时间限制:3500ms: 运行空间限制:262144KB: 代码长度限制:2000000B 试题描述 WZJ的数据结构中有很多都是关于树的.这让很多练习 ...

  2. 智课雅思词汇---十九、前缀se是什么意思

    智课雅思词汇---十九.前缀se是什么意思 一.总结 一句话总结:前缀:se- 表示“分开, 离开, 区别开” 前缀:se- [词根含义]:分离 [同源单词]:secede, secession, s ...

  3. 无废话ExtJs 入门教程十九[API的使用]

    无废话ExtJs 入门教程十九[API的使用] extjs技术交流,欢迎加群(201926085) 首先解释什么是 API 来自百度百科的官方解释:API(Application Programmin ...

  4. Python之路【第十九章】:Django进阶

    Django路由规则 1.基于正则的URL 在templates目录下创建index.html.detail.html文件 <!DOCTYPE html> <html lang=&q ...

  5. Bootstrap <基础二十九>面板(Panels)

    Bootstrap 面板(Panels).面板组件用于把 DOM 组件插入到一个盒子中.创建一个基本的面板,只需要向 <div> 元素添加 class .panel 和 class .pa ...

  6. Bootstrap <基础十九>分页

    Bootstrap 支持的分页特性.分页(Pagination),是一种无序列表,Bootstrap 像处理其他界面元素一样处理分页. 分页(Pagination) 下表列出了 Bootstrap 提 ...

  7. Web 开发人员和设计师必读文章推荐【系列二十九】

    <Web 前端开发精华文章推荐>2014年第8期(总第29期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...

  8. Web 前端开发精华文章集锦(jQuery、HTML5、CSS3)【系列十九】

    <Web 前端开发精华文章推荐>2013年第七期(总第十九期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各种增强网站用户体验的 jQuery 插件,展示前沿的 HTML5 和 C ...

  9. Python之路【第十九篇】:爬虫

    Python之路[第十九篇]:爬虫   网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本.另外一些不常使用 ...

随机推荐

  1. ES集群7.3.0设置快照,存储库进行索引备份和恢复等

    说明:三台ES节点组成ES集群,一台kibana主机,版本均是7.3.0,白金试用版 官方地址:https://www.elastic.co/guide/en/elasticsearch/refere ...

  2. jmeter(二十七)分布式压测注意事项

    之前的博客:jemter(二十三):分布式测试简略的介绍了利用jmeter做分布式测试的方法,当时只是介绍了背景和原因,以及基本的配置操作,有同学说写得不够详细. 正好今年双十一,我司的全链路压测,也 ...

  3. 示例:WPF中自定义StoryBoarService在代码中封装StoryBoard、Animation用于简化动画编写

    原文:示例:WPF中自定义StoryBoarService在代码中封装StoryBoard.Animation用于简化动画编写 一.目的:通过对StoryBoard和Animation的封装来简化动画 ...

  4. 关于注解sql和动态sql的写法

    注解写sql一般写在mapper层,如果sql语句复杂建议不要写注解sql 拼接容易出错 二动态sql的话要在 main 下面创建一个resource ——mapper—— Mapper.xml 再在 ...

  5. Ubuntu安装MySQL配置远程登录、utf8mb4字符集

    2019/11/19, Ubuntu Server 18.04,MySQL 5.7 摘要:Ubuntu Server 18.04 安装MySQL 5.7 并配置远程登录.utf8mb4字符集 由于My ...

  6. Android studio 混淆配置

    混淆 studio 使用Proguard进行混淆,其是一个压缩.优化和混淆java字节码文件的一个工具. 功能:Shrinking(压缩).Optimization(优化).Obfuscattion( ...

  7. xshell连接本地linux虚拟机速度很慢的解决办法

    今天发现用xshell连接centos太慢,网上查询后发现是因为ssh的服务端在连接时会自动检测dns环境是否一致导致的,修改为不检测即可. 修改文件位置:vi /etc/ssh/sshd_confi ...

  8. 2019 边锋游戏java面试笔试题 (含面试题解析)

      本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.边锋游戏等公司offer,岗位是Java后端开发,因为发展原因最终选择去了边锋游戏,入职一年时间了,也成为了面 ...

  9. dubbo循序渐进 - 使用Docker安装Nexus

    docker search nexus docker pull docker.io/sonatype/nexus3 mkdir -p /usr/local/nexus3/nexus-data /usr ...

  10. MTSC 2019 深圳站精彩议题第一波更新! | 七五折门票火热售票中

      MTSC(中国移动互联网测试开发大会)到今年已经成功举办了五届,这四年里,TesterHome社区一直秉持着务实.能落地.有深度.高质量.重分享的原则,从讲师邀请到内容筛选都严格把控,只为将最能提 ...