ent 生成的代码中client 提供了比较全的事务处理

启动单个事务进行处理

  1. // GenTx generates group of entities in a transaction.
  1. func GenTx(ctx context.Context, client *ent.Client) error {
  1. tx, err := client.Tx(ctx)
  1. if err != nil {
  1. return fmt.Errorf("starting a transaction: %v", err)
  1. }
  1. hub, err := tx.Group.
  1. Create().
  1. SetName("Github").
  1. Save(ctx)
  1. if err != nil {
  1. return rollback(tx, fmt.Errorf("failed creating the group: %v", err))
  1. }
  1. // Create the admin of the group.
  1. dan, err := tx.User.
  1. Create().
  1. SetAge(29).
  1. SetName("Dan").
  1. AddManage(hub).
  1. Save(ctx)
  1. if err != nil {
  1. return rollback(tx, err)
  1. }
  1. // Create user "Ariel".
  1. a8m, err := tx.User.
  1. Create().
  1. SetAge(30).
  1. SetName("Ariel").
  1. AddGroups(hub).
  1. AddFriends(dan).
  1. Save(ctx)
  1. if err != nil {
  1. return rollback(tx, err)
  1. }
  1. fmt.Println(a8m)
  1. // Output:
  1. // User(id=2, age=30, name=Ariel)
  1. // Commit the transaction.
  1. return tx.Commit()
  1. }
  1. // rollback calls to tx.Rollback and wraps the given error
  1. // with the rollback error if occurred.
  1. func rollback(tx *ent.Tx, err error) error {
  1. if rerr := tx.Rollback(); rerr != nil {
  1. err = fmt.Errorf("%v: %v", err, rerr)
  1. }
  1. return err
  1. }
 
 

事务client 封装

有时已经使用了 *ent.Client 但是我们需要支持事务,就可以使用次方法

  1. // WrapGen wraps the existing "Gen" function in a transaction.
  1. func WrapGen(ctx context.Context, client *ent.Client) error {
  1. tx, err := client.Tx(ctx)
  1. if err != nil {
  1. return err
  1. }
  1. txClient := tx.Client()
  1. // Use the "Gen" below, but give it the transactional client; no code changes to "Gen".
  1. if err := Gen(ctx, txClient); err != nil {
  1. return rollback(tx, err)
  1. }
  1. return tx.Commit()
  1. }
  1. // Gen generates a group of entities.
  1. func Gen(ctx context.Context, client *ent.Client) error {
  1. // ...
  1. return nil
  1. }
 
 

最佳实践

  • 一个可重用的事务帮助方法
  1. func WithTx(ctx context.Context, client *ent.Client, fn func(tx *ent.Tx) error) error {
  1. tx, err := client.Tx(ctx)
  1. if err != nil {
  1. return err
  1. }
  1. defer func() {
  1. if v := recover(); v != nil {
  1. tx.Rollback()
  1. panic(v)
  1. }
  1. }()
  1. if err := fn(tx); err != nil {
  1. if rerr := tx.Rollback(); rerr != nil {
  1. err = errors.Wrapf(err, "rolling back transaction: %v", rerr)
  1. }
  1. return err
  1. }
  1. if err := tx.Commit(); err != nil {
  1. return errors.Wrapf(err, "committing transaction: %v", err)
  1. }
  1. return nil
  1. }
 
 
  • 使用
  1. func Do(ctx context.Context, client *ent.Client) {
  1. // WithTx helper.
  1. if err := WithTx(ctx, client, func(tx *ent.Tx) error {
  1. return Gen(ctx, tx.Client())
  1. }); err != nil {
  1. log.Fatal(err)
  1. }
  1. }

参考资料

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. HTML5 Canvas实战之刮奖效果【转】

    开源项目地址:https://github.com/artwl/Lottery 作者博客地址:http://www.cnblogs.com/jscode/p/3580878.html 谢谢浏览!

  2. BZOJ3277 串(后缀自动机)

    对多串建立SAM的一种方法是加分隔符.于是加完分隔符建出SAM. 考虑统计出每个节点被多少个串包含.让每个串各自在SAM上跑,跑到一个节点就标记(显然一定会完全匹配该节点,因为是对包含其的串建的SAM ...

  3. ping程序和tracert(traceroute)背后的故事--ICMP协议

    为路由器生,为交换机死,为了Ping通奋斗一辈子-----tracert.cn 上面是一个网络工程师的个人定位,很有意思,哈哈!那么我们来看看ping和tracert都是什么吧 PING (Packe ...

  4. MOOC 数据库笔记(五):关系演算

    关系演算 概述 (这部分的内容大多与离散数学有关,我没有相关基础,所以现在只是简单看一下) 关系演算是以数理逻辑中的谓词演算为基础的. 关系演算是描述关系运算的另一种思维方式. SQL语言是继承了关系 ...

  5. SUSE12Sp3-安装DockerCE和Docker-compose

    最近在写脚本.发现还是很方便的. Docker下载地址:https://download.docker.com/linux/static/stable/x86_64/ 执行以下脚本即可安装完毕. #! ...

  6. Python基础之datetime、sys模块

    1.datetime模块 1)datetime.datetime.now(),返回各当前时间.日期类型. datetime.datetime.now(),返回当前日期. import datetime ...

  7. JavaScript---正则使用,日期Date的使用,Math的使用,JS面向对象(工厂模式,元模型创建对象,Object添加方法)

    JavaScript---正则使用,日期Date的使用,Math的使用,JS面向对象(工厂模式,元模型创建对象,Object添加方法) 一丶正则的用法 创建正则对象: 方式一: var reg=new ...

  8. Python列表,元组,字典,集合

    列表 Python中列表是可变的,这是它区别于字符串和元组的最重要的特点,一句话概括即:列表可以修改,而字符串和元组不能. 列表追加数据的方法:append(),extend(数组),insert(位 ...

  9. Tensorflow快餐教程(1) - 30行代码搞定手写识别

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/lusing/article/details ...

  10. Django之ORM数据查询方式练习

    单表查询 单表查询简单示例 # 字段 models.DateField(auto_now_add) models.DateField(auto_now) # auto_now 和auto_now_ad ...