質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.35%

お金のようなデータを扱うシステムはどのようなアーキテクチャしたら良いでしょうか

解決済

回答 5

投稿 編集

  • 評価
  • クリップ 4
  • VIEW 1,121

score 175

分からないこと

会員のユーザー同士でお金のようなデータ(円やドル、仮想通貨、ポイントなど全てを含み、かつ法令を遵守できる、またユーザーにとって希少なもの)を交換するシステム(「送金」と表現することにします)をどのように作れば良いかわかりません。
ここで、想定しているのは、あるユーザーが別のユーザーに残高の一部を移動させるだけのシステムです。

追記(2019/10/25)

※法令遵守できるかどうかといった部分で、食い違いが起きてしまいましたので、より具体的なケースを記しました。

想定しているシステムについて追記します。
お金について、ユーザーが何らかの決済手段を用いて得た(購入したとは限りません)、サイト内のみ使えるポイントと定めます。
ここで、ポイントとは、あくまでサイトの所有物として、万が一紛失しても責任は問われないようなケースで、ユーザーにはそのことをよく理解しているものとします。

あるt時点のポイントのアカウントテーブルを次のように定めます。

id account user_id
1 100 a
2 70 b

上記のテーブルのt+1時点は、以下です。

id account user_id
1 90 a
2 80 b

id:1, user_id:aのアカウントから10引いて、id:2, user_id:bのアカウントに10足した状態を表現したということです。

上のシステムを作るとなった場合、どのようなアーキテクチャにしたら良いでしょうか。

考えたこと

私なりに考えたところ、

  1. 送金を表現するトランザクションログが、意義のある一定期間で保存が必要
  2. 現在の残高を表現するトランザクションログのスナップショットが必要
  3. データを絶対に紛失してはならない
  4. トランザクションの原子性、一貫性、独立性を満たす必要
  5. 4が満たされない(あってはならないバグが原因で)、または不正が行われた場合に、ある時点からリトライ・ある時点までロールバックできるようにすること

があるんじゃないかなと思いました。
5が思い浮かんだのは以前仮想通貨の取引所で、不具合が起きた時に、
残高やら取引履歴やらの全てが、不具合直前の状態が戻されたというニュースを聞いて、
印象に残っていたためです。

考えたことが全部合っている場合のアーキテクチャ

もし、上記の想定が合っているなら、
アプリケーションのアーキテクチャとして

  • トランザクションログとしてkafkaのようなMQ
  • at least onceなConsumerとして残高を冪等にRDBMSのデータベースへ記録するアプリケーション
  • ある時点までのトランザクションを入力とした強制ロールバック用のアプリケーション

またデータについては

  • 複数サーバーに同期的な書き込み
  • トランザクションログを3年分?アーカイブとして保存する

と思いました。

以上、金融システム実装のご経験のある方からお話を伺いたいです。

※法律で、資金力の問題や、免許を取得しなければならないといったシステムと直接関係のない問題は全て解決できるものとします。システムアーキテクチャに関係のある法令(ログは3ヵ月は保持しましょうというような)を満たさない可能性をご存知であれば、ご指摘いただきたいです。
※セキュリティとして、ユーザーや管理者の認証や認可は全て正しく行われているものとします。お金固有のこだわらなくてはならないポイントがあれば、教えていただきたいです

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • urbainleverrier

    2019/10/25 13:16 編集

    takasima20さんありがとうございます。
    リアルタイム性とはデータについて結果整合性を求めるかリアルタイム整合性を求めるかということですか?
    もしくは、レプリカ間のfsyncのことについてですか?
    取扱い可能な金額を考慮するとは、数字の型についてよく検討するということですか?
    全く見当違いであればコメントいただきたいです。

    キャンセル

  • m.ts10806

    2019/10/25 13:17

    でしたら「お金を送金」等の表現は改められた方が良いです。ポイントならまだ簡単な話ですが仮想通貨だとかなり難しい話になります。要は、要件定義を具体的にしないと話が進みませんということですね

    キャンセル

  • urbainleverrier

    2019/10/25 13:42

    タイトル、質問文、適宜訂正させていただきました。他、改めるべき箇所ございましたら、ご指摘いただければ幸いです。
    「要件定義を具体的に」というご指摘最もか、と思います。
    質問文、訂正いたします。

    キャンセル

回答 5

+2

設計以前の問題として、金融システム関連の法令・指針があるのはご存知ですか?
とりあえず、金融庁のページ貼っときます。
この中のどれを見ればいいかは知りませんが、個人でどうこう出来ることではありませんね。

https://www.fsa.go.jp/common/law/index.html

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/10/25 13:19

    各種法令があり、資金決済法やら送金業やら銀行業やら、がんじがらめになっているのは知っています。法令をないがしろにしようとは思っていませんので、どうかご安心ください。
    お聞きしたいのは、「絶対に不整合のあってはならないお金という性質を持つデータ」をどのように扱うべきかということです。
    どうかよろしくお願いいたします。

    キャンセル

+1

システム設計以前にサービス設計したほうが良いですよ。

ちなみに、法律/ガイドラインは「絶対に不整合のあってはならないお金という性質を持つデータ」をどのように扱うべきかということを明文化したものです。

サービス設計の基幹であり、最低限満たすべき要件です。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/10/25 14:06

    te2jiさん、ありがとうございます。
    よく法律について勉強しようと思います。

    キャンセル

  • 2019/10/25 14:12

    サービス設計後に参照されるのは、多くの場合 PCI DSS です。質問にあるような枝葉の話ではなくもう少し根幹の定義になります。

    キャンセル

  • 2019/10/25 14:34

    te2jiさんありがとうございます。
    よく検討してみます。

    キャンセル

check解決した方法

0

みなさま、私の未熟故な質問に真摯に答えてくださり、ありがとうございました。
アドバイスを一つ一つ検討していきたいと思います。

また、こちらの質問はこの自己解決の投稿を持って一度閉めさせていただきます。
回答に対するコメント(お礼含む)も以降、省略させていただきますので、
ご理解のほどよろしくお願いいたします。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

その、送金、というのは具体的になにをするんでしょうか。

全てそれにかかってきますが。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/10/25 14:02

    ご不快に思わせてしまい、申し訳ございません。
    「現金書留」を使う想定はしておりませんでした。
    質問文、コメントいただいた後で、訂正させていただきました。
    私の質問文の内容が不足しておりました。
    ここで、お金とは、必ずしも国で定めたような広く流通するお金とは限らず、ユーザーにとって希少なもの=お金として読んでいただければ幸いです。

    キャンセル

  • 2019/10/25 14:14

    実際のカネじゃなければ、すきにすればいい、という話になりますね。
    どれだけのことを許され、どれだけのことが許されないというのはあなたの頭の中にしかありませんし

    キャンセル

  • 2019/10/25 14:34

    y_waiwaiさんありがとうございます。
    よく検討してみます。

    キャンセル

0

不整合な状態にならないようにしたいなら BeginTransaction~Commit or Rollback すればいいし、
ある時点に戻す必要があるのであれば適切な頻度でバックアップ取ればいいのではないでしょうか。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/10/25 16:54

    workaholistさんありがとうございます。
    私も、バックアップを取ることで実現できるのではないかと思いました。
    しかし、ふと残高テーブルとは、送金というEventを大切にして、EventStreamのある時点の状態を表現すしたものに過ぎないんじゃないかなと思いました。
    要するに、EventStreamにある送金Eventの連なりが真実であり、最も重要なデータで、残高テーブルが多少間違っていたとしても、EventStreamをもう一度さらえば残高テーブルをいつでも表現できるという状態が最も望ましいのではないかなと思いました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.35%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問