ホームページ >ウェブフロントエンド >jsチュートリアル >React Query でのデータベース クエリの分散ロックの実装

React Query でのデータベース クエリの分散ロックの実装

PHPz
PHPzオリジナル
2023-09-28 08:42:231049ブラウズ

在 React Query 中实现数据库查询的分布式锁定

React Query でのデータベース クエリの分散ロックの実装

はじめに:
最新の Web アプリケーションでは、多くの場合、バックエンド データベースと対話する必要があります。同時実行性の問題は、複数のユーザーが同時にデータベースにアクセスし、同じデータを変更する場合に発生します。同時実行性の問題を回避するには、分散ロックが一般的な解決策です。この記事では、React Query で分散ロックを使用してデータベース クエリを実装する方法を紹介します。

React Query は、React アプリケーションでのデータの取得、更新、管理を簡単にする強力なデータ管理ライブラリです。 「クエリ参照」と呼ばれる概念を使用しており、異なる種類のクエリを 1 つの「クエリ」に結合することで、必要に応じて複数のクエリと更新操作を簡単に実行できます。

React Query でデータベース クエリの分散ロックを実装するには、カスタム クエリ フックとデータベースのオプティミスティック ロック メカニズムを使用できます。

1. カスタム クエリ フック
まず、データベース クエリ操作を実行するためのカスタム クエリ フックを作成する必要があります。このフックは、ネットワーク リクエストの送信とデータの返しを担当します。

import { useQuery } from 'react-query';
import axios from 'axios';

const useDatabaseQuery = (query) => {
  const fetchQuery = async () => {
    const response = await axios.get('/api/database', { params: { query } });
    return response.data;
  };

  return useQuery(query, fetchQuery);
};

export default useDatabaseQuery;

上記のコードでは、Axios ライブラリを使用してネットワーク リクエストを送信します。バックエンド API 構成とデータベース構成に基づいて、適切な変更を行う必要があります。

2. クエリ操作のマージ
次に、React Query のクエリ参照メカニズムを使用して、複数のクエリ操作を複合クエリにマージします。これにより、複合クエリで複数のクエリの結果が同時に取得されることが保証されます。

import { useQueries } from 'react-query';
import useDatabaseQuery from './useDatabaseQuery';

const useCombinedQueries = () => {
  const query1 = useDatabaseQuery('SELECT * FROM table1');
  const query2 = useDatabaseQuery('SELECT * FROM table2');
  const query3 = useDatabaseQuery('SELECT * FROM table3');

  return useQueries([query1, query2, query3]);
};

export default useCombinedQueries;

上記のコードでは、useDatabaseQuery カスタム クエリ フックを使用して 3 つの個別のクエリを作成しました。次に、それらを useQueries 関数に入れて、すべてのクエリ操作が一度に実行されるようにします。

3. 分散ロックの実装
データベース クエリの分散ロックを実現するために、データベースのオプティミスティック ロック メカニズムを使用できます。オプティミスティック ロックはオプティミスティック同時実行制御戦略であり、複数のユーザーが同時に同じデータを読み取ることができますが、データを変更して保存できるのは 1 人のユーザーだけです。

まず、特定の行をロックまたはロック解除としてマークする追加のロック フィールドをデータベース テーブルに追加します。

-- 创建表
CREATE TABLE my_table (
  id SERIAL PRIMARY KEY,
  content TEXT,
  is_locked BOOLEAN DEFAULT FALSE
);

次に、クエリ操作を実行する前に、対応するデータ行を取得してロックする必要があります。

import { useMutation, queryCache } from 'react-query';
import axios from 'axios';

const lockQuery = async (id) => {
  const response = await axios.post('/api/database/lock', { id });
  return response.data;
};

const unlockQuery = async (id) => {
  const response = await axios.post('/api/database/unlock', { id });
  return response.data;
};

const useLockQuery = (query) => {
  const mutation = useMutation(lockQuery);
  const unlockMutation = useMutation(unlockQuery);

  const lock = async (id) => {
    await mutation.mutateAsync(id);
    queryCache.invalidateQueries(query); // 清理缓存
  };

  const unlock = async (id) => {
    await unlockMutation.mutateAsync(id);
    queryCache.invalidateQueries(query); // 清理缓存
  };

  return { lock, unlock, isLocked: mutation.isLoading };
};

export default useLockQuery;

上記のコードでは、2 つの非同期ミューテーション関数 lockQueryunlockQuery を作成しました。これらは、それぞれ特定のデータ行をロックおよびロック解除するために使用されます。次に、useMutation 関数を使用して、これら 2 つの突然変異を宣言します。

最後に、データを取得し、特定のデータ行をロックするために、カスタム クエリ フックに useLockQuery フックを導入します。同時に、データ行のロックを解除する必要がある場合は、unlock 関数を呼び出してデータ行のロックを解除できます。

4. 分散ロックを使用したクエリ
これで、React コンポーネントで useCombinedQueriesカスタム クエリ フックと useLockQuery フックを使用できるようになりました。

import useCombinedQueries from './useCombinedQueries';
import useLockQuery from './useLockQuery';

const MyComponent = () => {
  const combinedQueries = useCombinedQueries();
  const { lock, unlock, isLocked } = useLockQuery('SELECT * FROM my_table');

  const handleLockClick = (id) => {
    lock(id);
  };

  const handleUnlockClick = (id) => {
    unlock(id);
  };

  return (
    <div>
      {combinedQueries.map((query, index) => (
        <div key={index}>
          {query.isFetching ? (
            <p>Loading...</p>
          ) : query.error ? (
            <p>Error: {query.error.message}</p>
          ) : (
            <>
              <p>Data: {query.data}</p>
              <button onClick={() => handleLockClick(query.data.id)} disabled={isLocked}>Lock</button>
              <button onClick={() => handleUnlockClick(query.data.id)}>Unlock</button>
            </>
          )}
        </div>
      ))}
    </div>
  );
};

export default MyComponent;

上記のコードでは、useCombinedQueriesカスタム クエリ フックを使用してデータベースからデータを取得します。次に、useLockQuery フックを使用して、データの特定の行をロックおよびロック解除します。最後に、クエリのステータスとデータ行がロックされているかどうかに基づいて、対応する UI を表示します。

概要:
React Query とカスタム クエリ フックを使用すると、データベース クエリの分散ロックを簡単に実装できます。この方法は、データベースに同時にアクセスする際のデータの一貫性と同時実行性の制御を保証するためのオプティミスティック ロックの考え方を組み合わせています。

実際の使用では、特定のビジネス ニーズとバックエンド API 実装に基づいて、対応する変更と調整を行う必要があることに注意してください。この記事で提供されているコード例は参照のみを目的としています。

以上がReact Query でのデータベース クエリの分散ロックの実装の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。