4

我是函数式编程和 Clojure 的新手,所以我不太确定在大学里为项目做什么。该项目应展示 Clojure STM 在银行交易中的优势(将资金从账户 A 转移到账户 B)。所以我打算这样进行:

  1. 定义初始数据,如 Refs 矩阵或更好的东西
  2. 生成随机操作来执行:[ random-account-source-id(0, N_MAX) , random-account-destination-id(0, N_MAX), random-money (0, 1000) ]
  3. 将事务插入数据结构
  4. 对于矩阵中的所有插入,将资金从源 ID 同步转移到目的地 ID,例如:
    
    for i=0; i lt N; i++;
        synchronize: transfer (matrix[i].source,matrix[i].dest,matrix[i].money)
    

那么,我不确定这一点,也许:

(defn do-all[]
  (dosync
    (when (pos? N)
      (transfer (get matrix [pos 1], get matrix [pos 2], get matrix [pos 3])))))
4

2 回答 2

6

用 Ref 表示账户,即每个账户的 Ref 并在 dosync 操作中执行汇款操作。还要确保在 dosync 操作中不要执行任何副作用操作(除了那些 Refs),因为在更新 refs 时可能会在发生冲突的情况下重试。

更新: 如果您将固定帐户数量,那么您可以使用向量的参考,其中向量中的每个参考都是一个帐户,每个帐户由向量中的索引标识。

前任:

(def total-accounts 100)
(def accounts (vec (map (fn [_] (ref 100)) (range total-accounts))))

如果您必须动态添加新帐户并按名称识别它们,那么您可以使用哈希映射,其中键是帐户 ID(唯一值),值是帐户余额的 Ref。您需要将此映射包装在 Ref 中,以防您想要执行并发操作以从多个线程中添加/删除帐户。

于 2012-03-03T15:32:05.920 回答
4

您可能对我在回答另一个问题时发布的用于银行交易的 Clojure STM 示例感兴趣。

于 2012-03-04T01:37:28.663 回答