ORM支持传递自定义的context上下文变量,用于异步IO控制、上下文信息传递(特别是链路跟踪信息的传递)、以及嵌套事务支持。

我们可以通过Ctx方法传递自定义的上下文变量给ORM对象,Ctx方法其实是一个链式操作方法,该上下文传递进去后仅对当前DB接口对象有效,方法定义如下:

  1. func Ctx(ctx context.Context) DB

示例1,请求超时控制

我们来看一个通过上下文变量控制请求超时时间的示例。

  1. ctx, cancel := context.WithTimeout(context.Background(), time.Second)
  2. defer cancel()
  3. _, err := db.Ctx(ctx).Query("SELECT SLEEP(10)")
  4. fmt.Println(err)

该示例中执行会sleep 10秒中,因此必定会引发请求的超时。执行后,输出结果为:

  1. context deadline exceeded, SELECT SLEEP(10)

示例2,链路跟踪信息

上下文变量也可以传递链路跟踪信息,并且可以和日志组件结合,将链路信息打印到日志中(仅当ORM日志开启时)。

我们来看一个示例。

1、数据库配置示例:

  1. [database]
  2. [database.logger]
  3. Path = "/tmp/log/gf-app/sql"
  4. Level = "all"
  5. Stdout = true
  6. CtxKeys = ["Trace-Id"]
  7. [database.default]
  8. link = "mysql:root:12345678@tcp(127.0.0.1:3306)/test"
  9. debug = true

其中,我们通过日志组件的CtxKeys配置来指定需要打印到日志中的上下文信息中的变量名称,因此当context上下文变量中存在键名为Trace-Id的变量时,将会被自动打印到日志中。关于日志组件的上下文特性介绍具体请参考 日志组件-Context上下文 章节。同时,仅当数据库配置的debug打开时才会记录完整的SQL执行日志,因此这里配置中的debug=true

ORM组件同时支持goframe框架的logger组件CtxKeys特性(自定义链路信息传递),同时也支持标准的OpenTelemetry链路跟踪信息传递,具体请参考章节:链路跟踪

2、Golang代码示例

  1. package main
  2. import (
  3. "context"
  4. "github.com/gogf/gf/frame/g"
  5. )
  6. func main() {
  7. ctx := context.WithValue(context.Background(), "Trace-Id", "123456789")
  8. _, err := g.DB().Ctx(ctx).Query("SELECT 1")
  9. if err != nil {
  10. panic(err)
  11. }
  12. }

为简化示例,我们这里手动构造了一个ctx变量,并存放了一个Trace-Id的键值对,键值为123456789。执行后,终端输出为:

  1. 2020-12-28 23:43:03.055 [DEBU] {Trace-Id: 123456789} [ 3 ms] [default] SELECT 1

示例3,模型上下文操作

模型对象也支持上下文变量的传递,同样也是通过Ctx方法。我们来看一个简单的示例,我们将示例2的例子通过模型操作调整一下。

  1. package main
  2. import (
  3. "context"
  4. "github.com/gogf/gf/frame/g"
  5. )
  6. func main() {
  7. ctx := context.WithValue(context.Background(), "Trace-Id", "123456789")
  8. _, err := g.DB().Model("user").Ctx(ctx).All()
  9. if err != nil {
  10. panic(err)
  11. }
  12. }

执行后,终端输出为:

  1. 2020-12-28 23:46:56.349 [DEBU] {Trace-Id: 123456789} [ 5 ms] [default] SHOW FULL COLUMNS FROM `user`
  2. 2020-12-28 23:46:56.354 [DEBU] {Trace-Id: 123456789} [ 5 ms] [default] SELECT * FROM `user`

其中SHOW FULL COLUMNS FROM `user` ORM组件的数据表字段获取查询,每个表在执行操作之前仅会查询一次并缓存结果到内存中。

示例4,嵌套事务支持

嵌套事务的支持依赖Context上下文变量的层级传递,具体请参考章节:ORM事务处理

Content Menu