haskell - Haskell 中的并发数据库连接池

标签 haskell rdbms connection-pooling hdbc

我是一名学习 Haskell 的 Java 程序员。
我在一个使用 Happstack 并通过 HDBC 与数据库对话的小型网络应用程序上工作。

我写过 选择执行 函数,我像这样使用它们:

module Main where

import Control.Exception (throw)

import Database.HDBC
import Database.HDBC.Sqlite3 -- just for this example, I use MySQL in production

main = do
    exec "CREATE TABLE IF NOT EXISTS users (name VARCHAR(80) NOT NULL)" []

    exec "INSERT INTO users VALUES ('John')" []
    exec "INSERT INTO users VALUES ('Rick')" []

    rows <- select "SELECT name FROM users" []

    let toS x = (fromSql x)::String
    let names = map (toS . head) rows

    print names

如您所见,非常简单。有查询 , 参数 结果 .
连接创建和提交/回滚内容隐藏在 select 和 exec 中。
这很好,我不想在我的“逻辑”代码中关心它。
exec :: String -> [SqlValue] -> IO Integer
exec query params = withDb $ \c -> run c query params

select :: String -> [SqlValue] -> IO [[SqlValue]]
select query params = withDb $ \c -> quickQuery' c query params

withDb :: (Connection -> IO a) -> IO a
withDb f = do
    conn <- handleSqlError $ connectSqlite3 "users.db"
    catchSql
        (do r <- f conn
            commit conn
            disconnect conn
            return r)
        (\e@(SqlError _ _ m) -> do
            rollback conn
            disconnect conn
            throw e)

坏点:
  • 每次调用都会创建一个新连接 - 这会在重负载时降低性能
  • DB url "users.db"是硬编码的 - 我无法在其他项目中重用这些函数而无需编辑

  • 问题 1:如何引入具有一些已定义(最小,最大)并发连接数的连接池,以便在 select/exec 调用之间重用连接?

    问题 2:如何使“users.db”字符串可配置? (如何将其移至客户端代码?)

    它应该是一个透明的特性:用户代码不应该需要明确的连接处理/释放。

    最佳答案

    resource-pool包提供了一个高性能的资源池,可用于数据库连接池。例如:

    import Data.Pool (createPool, withResource)
    
    main = do
        pool <- createPool newConn delConn 1 10 5
        withResource pool $ \conn -> doSomething conn
    

    创建一个包含 1 个子池和最多 5 个连接的数据库连接池。每个连接在被销毁之前允许空闲 10 秒。

    关于haskell - Haskell 中的并发数据库连接池,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1141677/

    相关文章:

    haskell - 需要为 Yesod 路径定义哪些类型类?

    haskell - 派生 GADT 的读取实例

    haskell - 如果跌倒

    java - 无守护程序关系数据库管理系统

    scala - 如何将mongodb与casbah的连接池化?

    list - 测试我的代码时出现大索引问题

    java - 用于 Java 的异步数据库 API

    java - 连接池设计

    Java DBCP不断创建新连接

    mysql - 如果我们通过代码管理唯一性和自动增量,为什么要使用主键?