[英]How to cause Buffalo transaction middleware to commit?
在尝试使用 buffalo-pop/pop/popmw Transaction
中间件时,我没有成功写入数据库。 没有返回错误,调试 output 显示 SQL 语句,但未提交更新和插入。
处理程序看起来像:
func MyHandler(c buffalo.Context) error {
tx, ok := c.Value("tx").(*pop.Connection)
if !ok {
return errors.New("no transaction found")
}
f := models.File{
Name: "file.txt",
}
if err := tx.Create(&f); err != nil {
return err
}
return nil
}
app.go:
func App() *buffalo.App {
...
app.GET("/myhandler", MyHandler)
app.Use(popmw.Transaction(models.DB))
...
}
如果我使用DB, _:= pop.Connect("development")
进行连接,它可以正常工作。 我还观察到,每次点击此处理程序时,表上的自动增量值都会发生变化。
在实际应用中,我们无法调用c.Render
来报告响应代码,因为我们使用gqlgen
作为 http 处理程序。 它看起来像这样:
func GQLHandler(c buffalo.Context) error {
h := handler.GraphQL(gqlgen.NewExecutableSchema(gqlgen.Config{Resolvers: &gqlgen.Resolver{}}))
newCtx := context.WithValue(c.Request().Context(), "BuffaloContext", c)
h.ServeHTTP(c.Response(), c.Request().WithContext(newCtx))
return nil
}
Buffalo 的 Pop 中间件的功能之一是将操作和下面的中间件包装在数据库事务中的堆栈中。 以下是 Pop 中间件自动提交的条件:
- 如果执行中间件和操作没有错误,则提交; 响应状态为 2xx 或 3xx。
- 否则回滚。
因此,请确保在您的操作或堆栈的中间件中没有返回错误; 并且产生的响应状态是 200-ish 或 300-ish。
如果 Buffalo 通过调用c.Render
没有收到响应代码,则 Transaction 中间件将请求视为不成功。 由于这个问题的上下文是 GraphQL using gqlgen,而c.Render
不能使用,我发现显式关闭事务有效。 像这样的东西:
func GQLHandler(c buffalo.Context) error {
gqlSuccess := true
h := handler.GraphQL(gqlgen.NewExecutableSchema(gqlgen.Config{Resolvers: &gqlgen.Resolver{}})),
handler.ErrorPresenter(
func(ctx context.Context, e error) *gqlerror.Error {
gqlSuccess = false
return graphql.DefaultErrorPresenter(ctx, e)
}))
newCtx := context.WithValue(c.Request().Context(), "BuffaloContext", c)
h.ServeHTTP(c.Response(), c.Request().WithContext(newCtx))
if !gqlSuccess {
return nil
}
tx, ok := c.Value("tx").(*pop.Connection)
if !ok {
return errors.New("no transaction found")
}
return tx.TX.Commit()
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.