# DB Cache Theory and Understanding

{% hint style="danger" %}
**Currently, the ProudNet DB system only works on Windows.**

Game databases are characterized by small transaction sizes, many accesses, and most of the data is repeatedly fetched and stored. The ProudNet database system caches this process to reduce the load on the database.
{% endhint %}

## Structure of DB Cache data

Data stored in the game database is handled in tree units, and this tree is composed of nodes.

<figure><img src="/files/VMoVwNJprCvdTmWrTJHK" alt=""><figcaption><p>Example of storing user account information in DB</p></figcaption></figure>

Each node has a parent, child relationship, and each node has a name-value pair, or <mark style="color:orange;">property field</mark>.

<figure><img src="/files/AsVEyHhTl82gWXXrwzMc" alt=""><figcaption><p>Table structure for storing the above user account information in DB</p></figcaption></figure>

The table name of the root node, which is the highest node of the data tree being loaded, and the table name of the child nodes must be different.

## Data access types for DB Cache

In a DB cache, the default usage is to exclusively load and handle data, and the ProudNet DB system provides the following types of access.

<table data-full-width="false"><thead><tr><th width="153">Access Type</th><th>Use case examples</th><th width="119">Cache or not</th><th width="107">Immediate return</th><th width="105">Whether exclusive loading is required</th><th>Internal processing</th></tr></thead><tbody><tr><td>Making unilateral data changes</td><td>Frequent information changes for player characters during gameplay</td><td>YES</td><td>YES</td><td>YES</td><td>Cache first in memory and then write to DB</td></tr><tr><td>Changing request-responsive data</td><td>Create a player character with a unique name</td><td>NO</td><td>NO</td><td>YES</td><td>If successful after writing to DB, cache in memory</td></tr><tr><td>Accessing non-proprietary data</td><td>Purchasing paid items on your web server</td><td>NO</td><td>NO</td><td>NO</td><td>If successful after writing to DB, cache in memory</td></tr></tbody></table>

### - Exclusive load

To avoid [**race conditions**](/proudnet.eng/proudnet-note/dictionary.md#race-condition), the DB cache system allows only one DB cache client to load the same data, which is called an <mark style="color:orange;">exclusive load</mark>.<br>

If the DB Cache System is already monopolized by one DB Cache Client and a new DB Cache Client requests exclusivity, the previous DB Cache Client will receive a request to transfer exclusivity and can accept or reject it. At this time, if the previous DB Cache Client unloads data, the new DB Cache Client will receive exclusive rights.

<figure><img src="/files/IVqwvUs5b8iF22cbjnRh" alt=""><figcaption><p>Gamer X owned by Server 1 is loaded exclusively by Server 2</p></figcaption></figure>

#### (1) Making unilateral data changes

<figure><img src="/files/GIESTa6O2rVcyeBFKIlp" alt=""><figcaption></figcaption></figure>

When you make a <mark style="color:orange;">unilateral data change</mark>, the data is immediately reflected in memory in the DB cache, and the change is actually written to the database some time later, i.e., the data is cached. Because the <mark style="color:orange;">unilateral data change</mark> processing returns immediately, there is no latency in the routine that changes the data, so there is no need to wait for the result to complete after the data change.<br>

The <mark style="color:orange;">unlock then lock</mark> process is not required as in the routine below.

```cpp
UpdateSomeData()
{
    lock(X);
    ...
    unlock(X);
    UnilateralUpdateSomeData(X);
    lock(X);
    ...
    unlock(X);
}
```

{% hint style="info" %} <mark style="color:orange;">Unilateral data changes</mark> are applied unconditionally to memory in the DB cache, but the changes might not be reflected in the records for which you set <mark style="color:orange;">DB Constraints</mark> on the database.

For this reason, we recommend that you do not set <mark style="color:orange;">DB Constraints</mark>, or if you do, use them only when you are sure. In a typical online game, database objects for gamers and objects in the world region can safely use <mark style="color:orange;">unilateral data changes</mark>.
{% endhint %}

#### (2) Changing request-responsive data

<mark style="color:orange;">Request-response data change</mark> is a request-response type, which works in the opposite way to <mark style="color:orange;">unilateral data change</mark>. The DB cache client requests the DB cache server to <mark style="color:orange;">change the request-response data</mark> and actually records it in the database to determine whether the recording is successful through the DB cache client.

<figure><img src="/files/DHlVAqdg2Zmbx7qhPnQZ" alt=""><figcaption></figcaption></figure>

<mark style="color:orange;">Request-response data changes</mark> are not really cache in the sense, but they do not reflect the changes in the DB cache until the actual record is successful, reducing the probability of record failures due to [**DB Constraints**](/proudnet.eng/proudnet-note/dictionary.md#db-constraints). When creating player characters that prohibit duplicate names in online games, we typically use <mark style="color:orange;">request-response data changes</mark>.

#### (3) Accessing non-proprietary data

<mark style="color:orange;">Unilateral data changes</mark> and <mark style="color:orange;">request-responsive data changes</mark> are limited to exclusively loaded data.

However, there are times when you want to read or write data that has already been exclusively loaded from another DB cache client. There may be cases where it is necessary to view or change the character information of a logged on player in an operation tool, such as when viewing the player character's information on a web server or adding or changing an item to the player character's bag on a paid item payment server.

<mark style="color:orange;">Accessing non-proprietary data</mark> is a feature for this purpose.

All <mark style="color:orange;">non-proprietary data access</mark> operates in a <mark style="color:orange;">request-responsive data changes</mark> manner, so it does not respond immediately, but is resistant to DB Constraints. Additionally, when data is changed non-exclusively, the DB cache client that loaded exclusively is notified that the data has been changed by another source.

<figure><img src="/files/kijaEkGsEgYnaRlHFNss" alt=""><figcaption></figcaption></figure>

## Direct DB access to data covered by the DB cache

The data status of the data tree loaded and handled by the DB cache is maintained in a more up-to-date state than that in the DB.\
This is because data is written to the DB cache first and then to the DB later.

As a result, if a user writes data directly to the DB, apart from the data tree covered by the DB cache, undesirable errors can occur because the data in the DB is slightly older.

This is a similar problem to the <mark style="color:orange;">data race condition</mark>.

<figure><img src="/files/fpUs3D8Cwo1zLD74knCN" alt=""><figcaption><p>Data race condition by DB cache vs. DB access</p></figcaption></figure>

ProudNet provides <mark style="color:orange;">data isolation</mark> to avoid <mark style="color:orange;">data race condition</mark> when trying to handle data tree handled by DB cache directly in the DB, which completely disenables the user's desired data tree from DB cache to prevent <mark style="color:orange;">data race condition</mark> from occurring even if the DB is accessed directly.

<figure><img src="/files/kN27QJjHv6o7LNiZH2EM" alt=""><figcaption><p>Data isolation</p></figcaption></figure>

The instructions are as follows.

> * If you call <mark style="color:orange;">Proud.CDbCacheClient2.RequestIsolateData(X)</mark> for a data tree that needs to be accessed directly from the DB, X will be isolated, and if X is already loaded, it will also be unloaded.
> * Once <mark style="color:orange;">Proud.IDbCacheClientDelegate2.OnDeisolateDataSuccess(X)</mark> is called, you can safely access X in the DB.
> * If X is isolated, the DB cache cannot load it.
> * If you have completed DB access to X, call <mark style="color:orange;">Proud.CDbCacheClient2.RequestDeisolateData()</mark> to release isolation.

<figure><img src="/files/QoML4ZlJWdQYF2CKwG6J" alt=""><figcaption><p>Data Isolation Usage</p></figcaption></figure>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.proudnet.com/proudnet.eng/proudnet/db_system/db_cache_ver2/theory.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
