You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

mysql-haskell中try函数Right分支未触发问题排查求助

mysql-haskell插入成功但请求挂起,分支未触发问题排查与解决

问题场景

使用servant和mysql-haskell编写服务器时,执行INSERT语句遇到异常行为:

  • 新用户插入请求:数据成功写入数据库,但Right分支代码未执行(控制台无"No exception occurred"输出),客户端请求一直挂起
  • 重复插入触发唯一键冲突:Left分支正常执行,控制台输出错误信息,客户端能收到响应

代码片段

...
result <- try $ M.query conn ("insert into `user` (`email`,`name`,`date_joined`) values (?, ?, NOW());") [M.One $ M.MySQLText "1@mail.ru", M.One $ M.MySQLText "username"]

case result of
      Right (defs,is) -> do 
                    putStrLn "No exception occurred"
                    print =<< Streams.toList is 
      Left e  -> putStrLn ("Caught exception: " ++ show (e :: M.ERRException))
...

环境信息

GHCi, version 9.4.8
mysql  Ver 8.0.36 for Linux on x86_64

问题原因

mysql-haskell的query函数设计用于处理会返回结果集的SQL语句(如SELECT),它会等待读取完整的结果流。但不带RETURNING子句的INSERT语句不会返回任何结果集,此时Streams.toList is会一直阻塞,等待不存在的数据流,导致Right分支后续代码无法执行,线程挂起,客户端请求也因此一直处于等待状态。

而触发唯一键冲突时,数据库直接返回错误,try捕获异常后进入Left分支,不需要处理结果流,所以流程能正常完成,客户端收到响应。

解决方法

方案1:用execute替代query(推荐)

mysql-haskell提供了execute函数,专门用于执行无结果返回的SQL语句(INSERT/UPDATE/DELETE等),它执行完成后直接返回受影响的行数,不会阻塞等待结果流:

...
result <- try $ M.execute conn 
  "insert into `user` (`email`,`name`,`date_joined`) values (?, ?, NOW());" 
  [M.One $ M.MySQLText "1@mail.ru", M.One $ M.MySQLText "username"]

case result of
  Right affectedRows -> do
    putStrLn $ "插入成功,影响行数:" ++ show affectedRows
  Left e -> putStrLn $ "Caught exception: " ++ show (e :: M.ERRException)
...

方案2:添加RETURNING子句获取结果(如需返回插入数据)

如果需要获取插入后的自增主键或其他字段,可以在INSERT语句后添加RETURNING子句,让数据库返回结果集,此时query和Streams.toList is能正常读取数据,不会阻塞:

...
-- 假设主键列名为id,根据实际表结构调整
result <- try $ M.query conn 
  "insert into `user` (`email`,`name`,`date_joined`) values (?, ?, NOW()) RETURNING id;" 
  [M.One $ M.MySQLText "1@mail.ru", M.One $ M.MySQLText "username"]

case result of
  Right (defs,is) -> do
    putStrLn "No exception occurred"
    rows <- Streams.toList is
    print rows
  Left e -> putStrLn $ "Caught exception: " ++ show (e :: M.ERRException)
...

内容的提问来源于stack exchange,提问作者Dmitry M

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 06:45:02