<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Drimil Mendapara</title>
    <description>The latest articles on Forem by Drimil Mendapara (@dkmen).</description>
    <link>https://forem.com/dkmen</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1899302%2F240c49e2-d1de-4e7f-9dc8-8c046f98089b.png</url>
      <title>Forem: Drimil Mendapara</title>
      <link>https://forem.com/dkmen</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/dkmen"/>
    <language>en</language>
    <item>
      <title>Ensuring Data Integrity in Multi-User Environments</title>
      <dc:creator>Drimil Mendapara</dc:creator>
      <pubDate>Sat, 31 Aug 2024 10:34:31 +0000</pubDate>
      <link>https://forem.com/dkmen/ensuring-data-integrity-in-multi-user-environments-21g8</link>
      <guid>https://forem.com/dkmen/ensuring-data-integrity-in-multi-user-environments-21g8</guid>
      <description>&lt;h2&gt;
  
  
  What is in Concurrency Control?
&lt;/h2&gt;

&lt;p&gt;Concurrency Control in databases refers to the methods and techniques used to ensure that multiple transactions can occur simultaneously without leading to data inconsistencies, corruption, or loss.&lt;/p&gt;

&lt;p&gt;A database handles more than one transaction at the same time, and some transactions may read and update the same data. This can lead to issues like dirty reads and write-write conflicts. To manage this, databases use techniques known as concurrency control techniques.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Lock-Based Concurrency Control&lt;/li&gt;
&lt;li&gt;Timestamp-Based Concurrency Control&lt;/li&gt;
&lt;li&gt;Multiversion Concurrency Control (MVCC)&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Lock Based Concurrency Control
&lt;/h2&gt;

&lt;p&gt;In this technique, transactions use a locking mechanism to update or modify data in the database. This method helps the database prevent conflicts and maintain consistency&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkj8hxdw9fm2qz2tkjfm1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkj8hxdw9fm2qz2tkjfm1.jpg" alt="Image description" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We basically use two types of locks for any database resources.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Shared Locks (S)&lt;/strong&gt;: Allow multiple transactions to read (or acquire a shared lock on) the same resource but prevent any transaction from modifying it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exclusive Locks (X)&lt;/strong&gt;: Allow a single transaction to both read and modify a resource. When a transaction holds an exclusive lock, no other transaction can acquire any type of lock (shared or exclusive) on that resource.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A shared lock is used when a transaction reads some data. During this time, the transaction acquires a shared lock, and more than one transaction can acquire a shared lock on the same database resource. However, when a transaction wants to update data, it acquires an exclusive lock. This lock is used when a transaction modifies or updates data. When one transaction acquires an exclusive lock, other transactions cannot acquire either a shared or an exclusive lock on that resource.&lt;/p&gt;

&lt;p&gt;We use two type of method into lock base concurrency control&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Two-Phase Locking (2PL)&lt;/strong&gt;: A protocol where transactions acquire all the necessary locks before releasing any of them. It consists of two phases:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Growing Phase&lt;/strong&gt;: The transaction acquires locks but does not release any.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shrinking Phase&lt;/strong&gt;: The transaction releases locks and cannot acquire any new locks.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Strict Two-Phase Locking (Strict 2PL)&lt;/strong&gt;: A stricter form of 2PL where transactions must hold all their locks until they commit or abort.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;We have to consider trade-offs between concurrency and locking. In lock-based concurrency control, a transaction may lock an entire page or table of the resource. While this approach reduces the number of locks the database has to manage, it also results in lower concurrency. This type of lock is called Coarse-Grained Locking. Alternatively, we can lock only the specific row that the transaction is used. Although this approach requires the database to manage more locks, it allows for higher concurrency, and is referred to as Fine-Grained Locking. Depending on our use case, we should choose the appropriate technique.&lt;/p&gt;

&lt;p&gt;In this concurrency technique, a deadlock situation can occur when one transaction acquires a resource that is needed by another transaction, and the other transaction acquires a resource that is needed by the first transaction. In such cases, a deadlock occurs. To resolve this, the database uses deadlock prevention and deadlock detection techniques.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Dead Lock Prevention&lt;/p&gt;

&lt;p&gt;We have two techniques Wait-Die and Wound-Wait Schemes&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Wait-Die&lt;/strong&gt;: If an older transaction requests a lock held by a younger transaction, it waits (wait). If a younger transaction requests a lock held by an older transaction, the younger transaction is aborted (die).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wound-Wait&lt;/strong&gt;: If an older transaction requests a lock held by a younger transaction, the younger transaction is aborted (wound). If a younger transaction requests a lock held by an older transaction, it waits (wait).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Dead Lock Detection&lt;/p&gt;

&lt;p&gt;The database system builds a graph where each node represents a transaction. An edge from T1 to T2 indicates that T1 is waiting for a lock held by T2. If this graph contains a cycle, a deadlock is detected.&lt;/p&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;Deadlock Resolution&lt;/p&gt;

&lt;p&gt;Once a deadlock is detected, the system resolves it by rolling back one or more transactions. The chosen transaction is known as the "victim.”&lt;/p&gt;

&lt;p&gt;The selection of a victim can be based on various criteria&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Minimum Cost&lt;/strong&gt;: The transaction that has made the least progress (e.g., has executed the fewest statements) is rolled back.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lowest Priority&lt;/strong&gt;: Transactions are assigned priorities, and the one with the lowest priority is rolled back.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After rolling back a transaction, it can be retried either immediately or after a certain delay.&lt;/p&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Timestamp-Based Concurrency Control
&lt;/h2&gt;

&lt;p&gt;Timestamp-Based Concurrency Control (TBCC) is a method used in database systems to ensure that transactions are executed in a serialisable manner without using locks. Instead of relying on locks, TBCC assigns a unique timestamp to each transaction and uses these timestamps to enforce the order of transaction execution.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdm8t8t9ag22sstax5gsr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdm8t8t9ag22sstax5gsr.png" alt="Image description" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this technique, when a transaction is incoming, we assign a unique timestamp to that transaction. If more than one transaction arrives at the same time, the system ensures that each transaction receives a unique timestamp.&lt;/p&gt;

&lt;p&gt;The database data has two types of timestamps that help handle concurrency in transactions.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Read Timestamp (RTS)&lt;/strong&gt;: The RTS of a data item is the largest timestamp of any transaction that has successfully read that data item.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Write Timestamp (WTS)&lt;/strong&gt;: The WTS of a data item is the largest timestamp of any transaction that has successfully written to that data item.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Operation Rules in Timestamp-Based Concurrency Control&lt;/p&gt;

&lt;p&gt;In TBCC, when a transaction tries to perform a read or write operation on a data item, the system compares the transaction’s timestamp with the RTS and WTS of the data item to decide whether the operation is allowed, aborted, or delayed.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Read Operation&lt;/p&gt;

&lt;p&gt;When transaction Ti try to access resource X with timestamp TS&lt;/p&gt;

&lt;p&gt;Condition 1: TS  ≤  WTS(X): The transaction is reading outdated data, meaning another transaction with a later timestamp has already written to X. then Ti is abort and rollback.&lt;/p&gt;

&lt;p&gt;Condition 2: TS ≥ WTS(X): The transaction is allowed to read the data. The RTS of X is updated with TS timestamp (RTS(X) = TS ).&lt;/p&gt;

&lt;p&gt;Example&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Transaction T1&lt;/strong&gt; (with timestamp 5) writes to data item X, setting WTS(X) = 5&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Transaction T2&lt;/strong&gt; (with timestamp 3) tries to read X. Since TS(T2) is less than WTS(X), T2 is aborted.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Write Operation&lt;/p&gt;

&lt;p&gt;When transaction Ti try to write resource X with timestamp TS&lt;/p&gt;

&lt;p&gt;Condition 1: TS  &amp;lt; RTS(X): The write operation would violate the order of operations, as a transaction with a later timestamp has already read X. then Ti is abort and rollback.&lt;/p&gt;

&lt;p&gt;Condition 2: TS &amp;lt; WTS(X): The write operation is ignored because the data item X has already been written by a newer transaction.&lt;/p&gt;

&lt;p&gt;Condition 3: TS ≥ WTS(X) and RTS(X): The write operation is allowed. The WTS of X is updated to TS(Ti)&lt;/p&gt;

&lt;p&gt;Example&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Transaction T1&lt;/strong&gt; (with timestamp 7) reads data item X, setting RTS(X) = 7&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Transaction T2&lt;/strong&gt; (with timestamp 5) tries to write to X, TS (T2) is less than RTS(X) so transaction is aborted and rollback&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Transaction T3&lt;/strong&gt; (with timestamp 8) tries to write to X, TS (T3) is  grater then RTS(X) and WTS(X) so transaction is allow to write or update&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Advantage
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;TBCC does not use locks, so there is no risk of deadlocks occurring.&lt;/li&gt;
&lt;li&gt;TBCC can be simpler to implement compared to some lock-based protocols because it avoids the complexities of lock management and deadlock resolution.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Disadvantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;TBCC may result in a higher number of transaction aborts, especially in systems with high contention, as transactions can frequently violate the timestamp order.&lt;/li&gt;
&lt;li&gt;TBCC requires maintaining additional information (RTS and WTS) for each data item, leading to higher storage and computational overhead.&lt;/li&gt;
&lt;li&gt;Certain transactions, especially those with earlier timestamps, may be repeatedly aborted if they conflict with many other transactions, leading to starvation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Multiversion Concurrency Control (MVCC)
&lt;/h2&gt;

&lt;p&gt;In this technique, the database maintains versions of the data to handle concurrency. When a transaction updates or adds data, the version of the data changes. This version is maintained in the database and used to manage concurrency.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyzb9ipeglmr9lnv6qcxq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyzb9ipeglmr9lnv6qcxq.jpg" alt="Image description" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are some key concepts which use into MVCC&lt;/p&gt;

&lt;h3&gt;
  
  
  Versions
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Data Item Versions&lt;/strong&gt;: Every data item in the database can have multiple versions. Each version represents the state of the data item at a particular point in time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transaction Timestamps&lt;/strong&gt;: Each transaction is assigned a unique timestamp or transaction ID (TxID) when it begins. This timestamp is used to identify which version of the data a transaction should see and modify.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Visibility Rules
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Readers&lt;/strong&gt;: A transaction can only see the version of a data item that was committed before the transaction began. This ensures that the transaction operates on a consistent snapshot of the database.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Writers&lt;/strong&gt;: When a transaction updates a data item, it creates a new version of that data item rather than modifying the existing version. This new version is not visible to other transactions until the transaction commits.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Commit and Garbage Collection
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;When a transaction commits, its changes (new versions of data items) become visible to other transactions. Old versions that are no longer needed (i.e., versions that are not visible to any active transaction) can be garbage collected or deleted.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How MVCC Works
&lt;/h3&gt;

&lt;p&gt;Scenario&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Initial Balance&lt;/strong&gt;: $1000&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transaction T1 (TS1)&lt;/strong&gt;: Reads the balance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transaction T2 (TS2)&lt;/strong&gt;: Updates the balance to $1200.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transaction T3 (TS3)&lt;/strong&gt;: Reads the balance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transaction T4 (TS4)&lt;/strong&gt;: Updates the balance to $1500.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Step-by-step ordering&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Initial State:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;The balance is &lt;strong&gt;$1000&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;One version exists in the database:

&lt;ul&gt;
&lt;li&gt;Balance: $1000, Timestamp: TS=0&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Transaction T1 (TS1):&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;T1&lt;/strong&gt; starts with a start timestamp &lt;strong&gt;TS1&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;T1 reads the balance. Since no other transactions have updated it yet, T1 sees the version of the balance with TS=0, which is &lt;strong&gt;$1000&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;T1 does not make any changes and continues with its operations.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Transaction T2 (TS2):&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;T2&lt;/strong&gt; starts with a start timestamp &lt;strong&gt;TS2&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;T2 updates the balance to &lt;strong&gt;$1200&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The database creates a new version of the balance with the value &lt;strong&gt;$1200&lt;/strong&gt; and tags it with T2’s start timestamp (TS2).&lt;/li&gt;
&lt;li&gt;The previous version (balance = $1000, TS=0) is still retained for transactions that started before T2.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Transaction T3 (TS3):&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;T3&lt;/strong&gt; starts with a start timestamp &lt;strong&gt;TS3&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;T3 attempts to read the balance. Since T3’s start timestamp is greater than T2’s timestamp but T2 has not yet committed, T3 sees the most recent committed version of the balance, which is still &lt;strong&gt;$1000&lt;/strong&gt; (TS=0).&lt;/li&gt;
&lt;li&gt;T3 does not see the new version created by T2 because T2 has not committed yet.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Transaction T4 (TS4):&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;T4&lt;/strong&gt; starts with a start timestamp &lt;strong&gt;TS4&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;T4 updates the balance to &lt;strong&gt;$1500&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The database creates another new version of the balance with the value &lt;strong&gt;$1500&lt;/strong&gt; and tags it with T4’s start timestamp (TS4).&lt;/li&gt;
&lt;li&gt;The versions in the database are now:

&lt;ul&gt;
&lt;li&gt;Balance: $1000, TS=0&lt;/li&gt;
&lt;li&gt;Balance: $1200, TS=TS2 (uncommitted)&lt;/li&gt;
&lt;li&gt;Balance: $1500, TS=TS4 (uncommitted)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Commit Order:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;T2 Commits&lt;/strong&gt;: When T2 commits, the version with &lt;strong&gt;$1200&lt;/strong&gt; becomes visible to subsequent transactions. The versions are now:

&lt;ul&gt;
&lt;li&gt;Balance: $1000, TS=0 (for older transactions)&lt;/li&gt;
&lt;li&gt;Balance: $1200, TS=TS2 (newly committed)&lt;/li&gt;
&lt;li&gt;Balance: $1500, TS=TS4 (uncommitted)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;T4 Commits&lt;/strong&gt;: When T4 commits, its version with &lt;strong&gt;$1500&lt;/strong&gt; becomes visible. The versions are now:

&lt;ul&gt;
&lt;li&gt;Balance: $1000, TS=0 (for older transactions)&lt;/li&gt;
&lt;li&gt;Balance: $1200, TS=TS2&lt;/li&gt;
&lt;li&gt;Balance: $1500, TS=TS4 (newly committed)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Post-Commit State:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;If any new transaction starts after both T2 and T4 have committed, it will see the balance of &lt;strong&gt;$1500&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Benefits Of MVCC&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Non-Blocking Reads&lt;/strong&gt;: Both T1 and T3 read the balance without waiting for T2 and T4 to commit, avoiding delays.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistent Views&lt;/strong&gt;: Each transaction operates on a consistent snapshot of the database. T1 and T3 see the initial balance, while T2 and T4 see updated values when they read after writing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No Locks Needed&lt;/strong&gt;: Transactions proceed without locking the data, reducing contention and allowing more transactions to proceed in parallel.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Disadvantages of MVCC&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Increased Storage Overhead&lt;/strong&gt; Keeping multiple versions of data items requires additional storage. Although garbage collection helps mitigate this, it still increases the complexity and resource usage of the database.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Complexity in Implementation&lt;/strong&gt;  The implementation of MVCC is more complex than traditional locking mechanisms, which can lead to higher maintenance and debugging costs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Potential for Long-Running Transactions to Cause Issues&lt;/strong&gt; Long-running transactions can see outdated data for extended periods, potentially leading to less timely or relevant reads.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical Examples
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Lock Base Concurrency Control

&lt;ul&gt;
&lt;li&gt;When multiple transactions frequently update the same set of data, lock-based concurrency control can effectively prevent conflicts.&lt;/li&gt;
&lt;li&gt;If the application requires strong consistency guarantees, locks ensure that only one transaction can modify a data item at a time.&lt;/li&gt;
&lt;li&gt;Where transactions involve complex operations that need to be executed atomically, locking ensures that other transactions cannot interfere until the transaction is complete.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Timestamp-Based Concurrency Control

&lt;ul&gt;
&lt;li&gt;When transactions frequently read and write the same data, TBC ensures that transactions are executed in a logical order based on their timestamps, reducing the chances of conflicts.&lt;/li&gt;
&lt;li&gt;Where transactions must be processed in a strict order to maintain consistency. TBC ensures that the order of transactions reflects the order in which they arrive.&lt;/li&gt;
&lt;li&gt;Where transactions can be easily rolled back and retried if they conflict with others.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Multiversion Concurrency Control

&lt;ul&gt;
&lt;li&gt;In applications where reads significantly outnumber writes, MVCC allows reads to proceed without blocking, improving overall performance.&lt;/li&gt;
&lt;li&gt;When applications need to ensure that transactions operate on a consistent snapshot of the database, MVCC allows transactions to see a consistent view of the data as it was when they started.&lt;/li&gt;
&lt;li&gt;Where multiple users interact with the database simultaneously, and the system needs to support high levels of concurrency without sacrificing performance.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Summary Of Use-Case&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Lock-Based Concurrency Control:&lt;/strong&gt; Best for scenarios with high write contention, strict consistency needs, and complex transactions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Timestamp-Based Concurrency Control:&lt;/strong&gt; Ideal for real-time systems, applications with high read-write conflicts, and scenarios requiring strict transactional order.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-version Concurrency Control (MVCC):&lt;/strong&gt; Suited for read-heavy workloads, systems needing snapshot isolation, and high-concurrency environments like OLTP systems.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We explored various concurrency control techniques, including Lock-Based Concurrency Control, Timestamp-Based Concurrency Control, and Multiversion Concurrency Control (MVCC). Detailed explanations and examples were provided to demonstrate how each method handles simultaneous transactions, particularly focusing on scenarios with multiple reads and writes.&lt;/p&gt;

</description>
      <category>database</category>
      <category>webdev</category>
      <category>backend</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>Understanding the JWT</title>
      <dc:creator>Drimil Mendapara</dc:creator>
      <pubDate>Thu, 08 Aug 2024 03:54:09 +0000</pubDate>
      <link>https://forem.com/dkmen/understanding-the-jwt-3pl5</link>
      <guid>https://forem.com/dkmen/understanding-the-jwt-3pl5</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;What Is JWT?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;JWT stands for json web token, it’s open stander use to transmit information between parties as a JSON object. It is compact, URL-safe, and used extensively in web applications for authentication and information exchange. &lt;/p&gt;

&lt;p&gt;JWTs are digitally signed using keys and secrets. We verify the JWT with these keys and the signature to authenticate the user. Most web systems use JWTs to authorize users to access certain resources.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Token Components&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A JWT has three main components: the header, the payload, and the signature. When we create a token, we pass the header and payload, and then the token generates the signature.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Headre - The header of a JWT contains metadata about the token. It includes three values: &lt;code&gt;alg&lt;/code&gt;, &lt;code&gt;typ&lt;/code&gt;, and &lt;code&gt;kid&lt;/code&gt;. The &lt;code&gt;alg&lt;/code&gt; specifies the algorithm used to sign the token, &lt;code&gt;typ&lt;/code&gt; indicates the token type, and kid is an optional parameter used to identify the key. Whether to include &lt;code&gt;kid&lt;/code&gt; depends on your use case.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "alg": "RS256", // allow [HS256,RS256,ES256]
  "typ": "JWT", // Specific Type Of token
  "kid": "12345" // Used to indicate which key was used to sign 
the JWT. This is particularly useful when multiple keys are in use
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Payload - In Payload we specify some custom data mostly add user specific data into payload like user id and role.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Signature - The signature is generated by encoding the header and payload with a secret key (for HS256) or signing them with a private key (for RSA), and then hashing the result. This signature is used to verify the token.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How Token Is Created&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;As we discussed, a JWT has three components: the header, the payload, and the signature. We provide the header and payload, and the signature is generated from them. After combining all these components, we create the token.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Header Encoding
Base64Url Encode({
  "alg": "RS256",
  "typ": "JWT"
}) → eyJhbGciOiAiUlMyNTYiLCAidHlwIjogIkpXVCJ9


// Payload Encoding
Base64Url Encode({
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}) → eyJzdWIiOiAiMTIzNDU2Nzg5MCIsICJuYW1lIjogIkpvaG4gRG9lIiwgImlhdCI6IDE1MTYyMzkwMjJ9


// Concatenate Encoded header and payload
ConcatenatedHash =  Base64Url Encode(Header) + "." + Base64Url Encode(Payload)

//Create Signature
Hash = SHA-256(ConcatenatedHash)
Signature = RSA Sign(Hash with Private Key) or HS256 Sign(Hash with secrate)

// Create Token
Token = Base64UrlEncode(Header) +"."+ Base64UrlEncode(Payload) +"."+ Signature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, the process to create a JWT is as follows: we encode the payload and headers, then generate the signature from them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcdeuzvecfimneavlrs48.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcdeuzvecfimneavlrs48.jpg" alt="Image Flow Diagram of how jwt is work" width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Verifying JWT Tokens&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Earlier, we discussed how to create a JWT. Now, let's discuss how to verify a JWT. The verification process is essentially the reverse of token creation. First, we decrypt the token using a secret or public key. Then, we concatenate the header and payload to generate a signature. If the generated hash matches the signature, the token is valid; otherwise, it is not valid.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Token we recive in this formate
Token = Base64UrlEncode(Header) +"."+ Base64UrlEncode(Payload) +"."+ Signature

// Decrypt Signature
TokenHash = RSA Decrypt(Hash with Public Key) or HS256 Sign(Hash with secrate)

// Generate Hash From Encoded Header and Payload
Hash = SHA-256(Base64UrlEncode(Header) +"."+ Base64UrlEncode(Payload))

// Compare Hash
if(TokenHash == Hash) "Valid"
else "Not Valid"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Benefits of Using JWT&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Security -&lt;/strong&gt; JWTs are digitally signed, ensuring the integrity and authenticity of the data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compact -&lt;/strong&gt; JWTs are small in size, making them efficient to transmit over the network.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Self-Contained -&lt;/strong&gt; JWTs contain all the necessary information about the user, reducing the need to query the database multiple times.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;JWT provides all the above benefits, making it a popular choice for most authentication mechanisms to authorize users. Additionally, JWT can be used with various authentication techniques, such as DPoP and others.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How to Use JWT in Your Code&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;To use JWT in code, we utilize the &lt;code&gt;jsonwebtoken&lt;/code&gt; npm package. There are two methods for working with JWTs: the straightforward method using a secret key and the key pair method (using public and private keys).&lt;/p&gt;

&lt;h3&gt;
  
  
  Using Secret
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import jwt from 'jsonwebtoken';

// Define the type for the payload
interface Payload {
  userId: number;
  username: string;
}

// Secret key for signing the JWT
const secretKey: string = 'your-very-secure-secret';

// Payload to be included in the JWT
const payload: Payload = {
  userId: 123,
  username: 'exampleUser'
};

// Sign the JWT
const token: string = jwt.sign(payload, secretKey, { expiresIn: '1h' });
console.log('Generated Token:', token);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import jwt from 'jsonwebtoken';

// Secret key for signing the JWT
const secretKey: string = 'your-very-secure-secret';

// Verify the JWT
try {
  const decoded = jwt.verify(token, secretKey) as Payload;
  console.log('Decoded Payload:', decoded);
} catch (err) {
  console.error('Token verification failed:', (err as Error).message);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Using KeyPair Method
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import * as jwt from 'jsonwebtoken';
import { readFileSync } from 'fs';

// Load your RSA private key
const privateKey = readFileSync('private_key.pem', 'utf8');

// Define your payload
const payload = {
  sub: '1234567890',
  name: 'John Doe',
  iat: Math.floor(Date.now() / 1000) // Issued at
};

// Define JWT sign options
const signOptions: jwt.SignOptions = {
  algorithm: 'RS256',
  expiresIn: '1h' // Token expiration time
};

// Generate the JWT
const token = jwt.sign(payload, privateKey, signOptions);
console.log('Generated JWT:', token);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import * as jwt from 'jsonwebtoken';
import { readFileSync } from 'fs';

// Load your RSA public key
const publicKey = readFileSync('public_key.pem', 'utf8');

// Define JWT verify options
const verifyOptions: jwt.VerifyOptions = {
  algorithms: ['RS256'] // Specify the algorithm used
};

try {
  // Verify the JWT
  const decoded = jwt.verify(token, publicKey, verifyOptions) as jwt.JwtPayload;

  console.log('Decoded Payload:', decoded);
} catch (error) {
  console.error('Error verifying token:', error);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In summary, JSON Web Tokens (JWTs) securely transmit information between parties using a compact format. RSA signing and verification involve using a private key for signing and a public key for verification. The TypeScript examples illustrate generating a JWT with a private RSA key and verifying it with a public RSA key, ensuring secure token-based authentication and data integrity.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>node</category>
      <category>security</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
