【入門編】 読み取り専用と読み書きトランザクション – Cloud Spanner

やあ。Cloud Spannerの世界へようこそ。
世界中のエンジニアが「究極のデータベース」と呼ぶこの怪物も、本質を掴んでしまえば、これほど心強い相棒はいないんだ。

今日は、Spannerを使いこなすための「登竜門」、トランザクションの使い分けについて話そう。ここさえ押さえれば、君はもうSpannerの挙動に迷うことはなくなるよ。

—

「読み取り」と「書き込み」、なぜ分かれているのか?

データベースの世界で一番の悩みは「整合性(みんなが同じ情報を見ている状態)」と「速度」のバランスなんだ。Spannerは、世界中のサーバーをまたいでデータを管理しているのに、まるで隣のパソコンにあるかのような整合性を実現している。

これを実現するために、Spannerは「読み取り専用」と「読み書き」という2つのモードを明確に分けているんだ。

1. 「読み書き(Read-Write)トランザクション」

これは「銀行の窓口」だと思ってほしい。
誰かが預金を引き出している間、他の人が勝手に残高を書き換えたら大変だよね? だから、このモードは「今から書き換えるから、みんなちょっと待っててね!」と周囲に合図を送り、安全を確保してから処理を行う。

  • 特徴: どんなに忙しくても、データが壊れることは絶対にない。
  • 代償: 安全確認をする分、少しだけスピードの負担がかかる。

2. 「読み取り専用(Read-Only)トランザクション」

こっちは「図書館の本」だ。
ただ内容を読みたいだけなら、誰かが別のページを読んでいるのを邪魔する必要はないよね? Spannerは「過去の特定の時点」のデータを指差して読むことができるから、他の書き込み処理を待たずに、爆速で結果を返せるんだ。

  • 特徴: 書き込みの邪魔をしない。そして、何より速い。
  • 代償: 「今、この瞬間の最新データ」というよりは、「ごくわずかに過去のデータ」を参照することもある(でも、ほとんど気にならないレベルだよ)。

—

日常の例で整理してみよう

君がカフェのアプリを作っていると想像してごらん。

  • メニューを見る時: 「読み取り専用」で十分だよね。何百人が同時にメニューを見ていても、サーバーは全く疲れない。
  • 注文を確定する時: 「読み書き」が必要だ。在庫を減らして、注文履歴を書き込む。ここは正確さが命だから、少しの手間(コスト)をかけても確実に処理するんだ。

—

実践:コードで見る使い分け

Spannerのライブラリを使うとき、意識するのはこの一点だけだ。

1. 読み取り専用の例:爆速で結果を返す
他の処理を待たせず、今のデータベースの状態をサッと見る
with database.snapshot() as snapshot:
results = snapshot.execute_sql(“SELECT name FROM Menu WHERE id = 1”)
for row in results:
print(row) # メニューを読み取るだけならこれでOK

2. 読み書きの例:確実に書き込む
注文が入った!在庫を減らして記録する
def update_order(transaction):
# ここでデータの整合性をしっかり守る
transaction.execute_sql(“UPDATE Inventory SET count = count – 1 WHERE item = ‘Coffee'”)

database.run_in_transaction(update_order)

—

伝説のアーキテクトからのアドバイス

初学者が一番やりがちな間違いは、「とりあえず全部読み書きトランザクションでやってしまうこと」だ。

これだと、カフェのメニューを見るだけで「書き込み用の行列」に並ばされることになる。結果、アプリが重くなってしまうんだ。

  • 「表示するだけなら Snapshot(読み取り専用)」
  • 「変える時だけ Transaction(読み書き)」

この鉄則を覚えるだけで、君が書くコードのパフォーマンスは劇的に変わる。Spannerは賢いシステムだから、君が「読み取り専用」と伝えてさえあげれば、世界中どこからでも最速で結果を届けてくれるはずだよ。

—

どうだい? Cloud Spannerの考え方が、少し身近になったかな。
「整合性を保ちながら、いかに速く捌くか」。この哲学を理解できた君なら、もうSpannerを恐れる必要はない。

次は、インデックスの話でもしようか。君のコードがさらに研ぎ澄まされるのを待っているよ。

コメント

タイトルとURLをコピーしました