<?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>DEV Community: EVan Wilson</title>
    <description>The latest articles on DEV Community by EVan Wilson (@wilson_evan_1efa5910f8855).</description>
    <link>https://dev.to/wilson_evan_1efa5910f8855</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%2F2057882%2F5c2141d1-0960-411f-bcda-4913cde39e54.jpeg</url>
      <title>DEV Community: EVan Wilson</title>
      <link>https://dev.to/wilson_evan_1efa5910f8855</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/wilson_evan_1efa5910f8855"/>
    <language>en</language>
    <item>
      <title>Javascirpt basic Part 1</title>
      <dc:creator>EVan Wilson</dc:creator>
      <pubDate>Wed, 23 Oct 2024 09:21:20 +0000</pubDate>
      <link>https://dev.to/wilson_evan_1efa5910f8855/javascirpt-basic-part-1-5bb3</link>
      <guid>https://dev.to/wilson_evan_1efa5910f8855/javascirpt-basic-part-1-5bb3</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk0k5130n3v7bxlpsxn4d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk0k5130n3v7bxlpsxn4d.png" alt="javascirpt basic Part 1" width="800" height="891"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>80%💥 of work time is wasted</title>
      <dc:creator>EVan Wilson</dc:creator>
      <pubDate>Sat, 21 Sep 2024 12:18:19 +0000</pubDate>
      <link>https://dev.to/wilson_evan_1efa5910f8855/80-of-development-time-is-wasted-on-communication-64b</link>
      <guid>https://dev.to/wilson_evan_1efa5910f8855/80-of-development-time-is-wasted-on-communication-64b</guid>
      <description>&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%2Fcz9r4yl0d8hrfik1da6k.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%2Fcz9r4yl0d8hrfik1da6k.png" alt="ineffective communication" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In our daily work, you realize that most of your time is spent in communication without any progress in the actual work. This is incredibly frustrating, but it's a necessary evil we can't seem to escape from.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;👧Talking with the UI designer: They only care if you've faithfully recreated their design.&lt;/li&gt;
&lt;li&gt;👧Talking with the front-end developer: They only focus on whether you've got the field key type wrong.&lt;/li&gt;
&lt;li&gt;🤷‍♂️Talking with the product manager: They only want to know when the feature will go live.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's pure bullshit! When do I get time to actually code if I'm stuck in meetings all day? Are you kidding me?&lt;/p&gt;

&lt;h2&gt;
  
  
  So, Where Did We Go Wrong?
&lt;/h2&gt;

&lt;p&gt;Is it that our communicated information has never aligned properly? This isn't something that can be solved by any project or product manager's organization alone. We genuinely need a unified communication mechanism. Every day, there's a massive pile of information that needs to be synced, especially API info, which is the most extensive and complex part of our development...&lt;/p&gt;

&lt;h2&gt;
  
  
  Is There a Solution?
&lt;/h2&gt;

&lt;p&gt;I've envisioned an ideal approach, something like what's illustrated below:&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%2Ffd2ssslippl6lxmud6b9.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%2Ffd2ssslippl6lxmud6b9.png" alt="work flows" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I think this is the correct and scientific way to communicate. It revolves around API development and entails collaborative communication among different participants to address asymmetric API information. From Product Requirements -&amp;gt; API Design -&amp;gt; Share API documentation (including a mockURL) -&amp;gt; API Debug -&amp;gt; API Testing -&amp;gt; Deploy, as long as the requirements remain unchanged and the API design is agreed upon, I won’t have to waste 80% of my time on communication.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Implement This Idea
&lt;/h2&gt;

&lt;p&gt;This plan looks perfect on paper! But how can we execute it effectively? I feel the product manager might not follow my lead. So, I tried to find a tool to solve this problem. Jira (for project management), Postman (for API management), and others didn’t quite fit until I found this tool: EchoAPI!&lt;/p&gt;

&lt;p&gt;I explored EchoAPI's product features and attempted to utilize it to complete this work mechanism:&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%2Fa8ftm7t4hshkudet585d.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%2Fa8ftm7t4hshkudet585d.png" alt="EchoAPI" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is my vision. I want to use this method to reduce communication barriers in development. Hopefully, this approach is useful for all of us and helps us reclaim our 80% of the time.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>devops</category>
      <category>softwaredevelopment</category>
      <category>java</category>
    </item>
    <item>
      <title>Javascript operators for Beginners</title>
      <dc:creator>EVan Wilson</dc:creator>
      <pubDate>Fri, 20 Sep 2024 12:07:25 +0000</pubDate>
      <link>https://dev.to/wilson_evan_1efa5910f8855/javascript-operators-for-beginners-2d95</link>
      <guid>https://dev.to/wilson_evan_1efa5910f8855/javascript-operators-for-beginners-2d95</guid>
      <description>&lt;h2&gt;
  
  
  1.JavaScript Basic
&lt;/h2&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%2Frdjlv06na9umtvk4owzc.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%2Frdjlv06na9umtvk4owzc.png" alt="JavaScript Basic" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2.Welcome to join in and contribute!
&lt;/h2&gt;

&lt;p&gt;welcome to join in and contribute! Click the link below to add more:👇👇👇 [&lt;a href="https://workspace.echoapi.com/user/invite?invitation_code=U336b1bb65c02000" rel="noopener noreferrer"&gt;https://workspace.echoapi.com/user/invite?invitation_code=U336b1bb65c02000&lt;/a&gt;].&lt;/p&gt;

&lt;p&gt;&lt;a href="https://workspace.echoapi.com/user/invite?invitation_code=U336b1bb65c02000" rel="noopener noreferrer"&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%2Fcdymtlsdlwgtzf6ua0ep.png" alt="JavaScript Basic" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can directly add your scripts in the "Processing Script" section under the "Post-response" tab. 🐋&lt;/li&gt;
&lt;li&gt;Once you're done, hit "send" to see if everything checks out.🦭&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>node</category>
    </item>
    <item>
      <title>DayJS Functions for Beginners: Contributions Welcome!</title>
      <dc:creator>EVan Wilson</dc:creator>
      <pubDate>Thu, 19 Sep 2024 12:38:28 +0000</pubDate>
      <link>https://dev.to/wilson_evan_1efa5910f8855/dayjs-methods-for-beginners-contributions-welcome-43jb</link>
      <guid>https://dev.to/wilson_evan_1efa5910f8855/dayjs-methods-for-beginners-contributions-welcome-43jb</guid>
      <description>&lt;p&gt;I've compiled a list of commonly used DayJS Functions to help beginners find what they need quickly and easily. Experienced developers are welcome to join in and contribute! Click the link below to add more:👇👇👇 [&lt;a href="https://workspace.echoapi.com/user/invite?invitation_code=U336b1bb65c02000" rel="noopener noreferrer"&gt;https://workspace.echoapi.com/user/invite?invitation_code=U336b1bb65c02000&lt;/a&gt;].&lt;/p&gt;

&lt;p&gt;&lt;a href="https://workspace.echoapi.com/user/invite?invitation_code=U336b1bb65c02000" rel="noopener noreferrer"&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%2Fcdymtlsdlwgtzf6ua0ep.png" alt="JavaScript Basic" width="587" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can directly add your scripts in the "Processing Script" section under the "Post-response" tab. 🐋&lt;/li&gt;
&lt;li&gt;Once you're done, hit "send" to see if everything checks out.🦭&lt;/li&gt;
&lt;/ul&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%2F7czercjokv92f4pm64ct.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%2F7czercjokv92f4pm64ct.png" alt="add scripts" width="800" height="612"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's a quick diagram to guide you:🦕&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%2F4jl7m7b5ju0bh73dclty.jpeg" 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%2F4jl7m7b5ju0bh73dclty.jpeg" alt="DayJS" width="800" height="1186"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>node</category>
      <category>programming</category>
    </item>
    <item>
      <title>PostgreSQL Insights: Understanding MVCC in Transactions</title>
      <dc:creator>EVan Wilson</dc:creator>
      <pubDate>Wed, 18 Sep 2024 10:50:36 +0000</pubDate>
      <link>https://dev.to/wilson_evan_1efa5910f8855/postgresql-insights-understanding-mvcc-in-transactions-5bbk</link>
      <guid>https://dev.to/wilson_evan_1efa5910f8855/postgresql-insights-understanding-mvcc-in-transactions-5bbk</guid>
      <description>&lt;h3&gt;
  
  
  PostgreSQL Insights: Understanding MVCC in Transactions
&lt;/h3&gt;

&lt;h4&gt;
  
  
  0. Introduction
&lt;/h4&gt;

&lt;p&gt;This article delves into the Multi-Version Concurrency Control (MVCC) mechanism commonly implemented in transaction modules. It explores the advantages and disadvantages of MVCC, along with its specific implementation in PostgreSQL.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Introduction to MVCC
&lt;/h4&gt;

&lt;p&gt;MVCC (Multi-Version Concurrency Control) is a method utilized in database management systems for handling concurrent access. Traditional concurrency control often relies on locking, ensuring that only one transaction can modify data at a time. However, this approach can lead to reduced concurrency and performance bottlenecks, especially in high-concurrency scenarios. MVCC addresses some limitations of the traditional locking mechanism by maintaining multiple versions of data. Each transaction sees a specific version, allowing read and write operations to execute without interfering with each other. Essentially, when a modification is made, a new version of the data is created instead of altering the original data directly. Other transactions can still access the old data, enhancing concurrency. Despite its benefits, MVCC can consume more memory due to multiple versions, particularly in high-concurrency environments.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Common Implementations of MVCC
&lt;/h4&gt;

&lt;p&gt;There are two prevalent approaches to implementing MVCC:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Backup Before Modifying:&lt;/strong&gt; Before modifying the old data, it is backed up to a separate space while the new data is written. Other transactions can read from this backup space, such as the rollback segment in MySQL's InnoDB engine.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Insert Instead of Modify:&lt;/strong&gt; Instead of modifying the existing data, new data is inserted.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Both methods achieve MVCC but require additional space. Comparing the two, the second method simplifies transaction rollback and avoids running out of backup space. The first method, however, simplifies cleanup and prevents data scans from increasing data reads. PostgreSQL adopts the second approach, implementing MVCC through insertion.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. MVCC Implementation in PostgreSQL
&lt;/h4&gt;

&lt;h5&gt;
  
  
  3.1 Visibility Determination
&lt;/h5&gt;

&lt;p&gt;For MVCC to work, the concept of data versioning must be defined. PostgreSQL's definition is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;HeapTupleFields&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;TransactionId&lt;/span&gt; &lt;span class="n"&gt;t_xmin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="cm"&gt;/* inserting xact ID */&lt;/span&gt;
    &lt;span class="n"&gt;TransactionId&lt;/span&gt; &lt;span class="n"&gt;t_xmax&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="cm"&gt;/* deleting or locking xact ID */&lt;/span&gt;

    &lt;span class="k"&gt;union&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;CommandId&lt;/span&gt;  &lt;span class="n"&gt;t_cid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="cm"&gt;/* inserting or deleting command ID, or both */&lt;/span&gt;
        &lt;span class="n"&gt;TransactionId&lt;/span&gt; &lt;span class="n"&gt;t_xvac&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="cm"&gt;/* old-style VACUUM FULL xact ID */&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;t_field3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;HeapTupleFields&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;HeapTupleHeaderData&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;union&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;HeapTupleFields&lt;/span&gt; &lt;span class="n"&gt;t_heap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;DatumTupleFields&lt;/span&gt; &lt;span class="n"&gt;t_datum&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;t_choice&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;ItemPointerData&lt;/span&gt; &lt;span class="n"&gt;t_ctid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="cm"&gt;/* current TID of this or newer tuple (or a speculative insertion token) */&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this structure, each tuple's header stores the transaction ID for data insertion (&lt;code&gt;t_xmin&lt;/code&gt;) and deletion or update (&lt;code&gt;t_xmax&lt;/code&gt;). A zero &lt;code&gt;t_xmax&lt;/code&gt; value indicates that the data hasn't been deleted or updated. These values are immutable once set.&lt;/p&gt;

&lt;p&gt;Consider an example where a record with &lt;code&gt;a=2&lt;/code&gt; and &lt;code&gt;b=2&lt;/code&gt; was inserted by a transaction with ID 10 (&lt;code&gt;t_xmin=10&lt;/code&gt;). Initially, &lt;code&gt;t_xmax=0&lt;/code&gt;, meaning it hasn't been deleted or updated. An &lt;code&gt;UPDATE&lt;/code&gt; statement changes &lt;code&gt;a&lt;/code&gt; to 6, setting &lt;code&gt;t_xmax&lt;/code&gt; to 11 (indicating that transaction 11 deleted it), and creates a new record (without modifying the original one). Although two records exist, visibility must be determined using transaction snapshots and commit logs.&lt;/p&gt;

&lt;p&gt;PostgreSQL uses snapshots to determine which transactions are currently active. A transaction's updates and writes are invisible to others if it hasn't completed. Snapshot data structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;SnapshotData&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;SnapshotSatisfiesFunc&lt;/span&gt; &lt;span class="n"&gt;satisfies&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="cm"&gt;/* tuple test function */&lt;/span&gt;
    &lt;span class="n"&gt;TransactionId&lt;/span&gt; &lt;span class="n"&gt;xmin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;      &lt;span class="cm"&gt;/* all XID &amp;lt; xmin are visible */&lt;/span&gt;
    &lt;span class="n"&gt;TransactionId&lt;/span&gt; &lt;span class="n"&gt;xmax&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;      &lt;span class="cm"&gt;/* all XID &amp;gt;= xmax are invisible */&lt;/span&gt;

    &lt;span class="n"&gt;TransactionId&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;xip&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;uint32&lt;/span&gt; &lt;span class="n"&gt;xcnt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;      &lt;span class="cm"&gt;/* # of xact IDs in xip[] */&lt;/span&gt;

    &lt;span class="n"&gt;TransactionId&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;subxip&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;int32&lt;/span&gt; &lt;span class="n"&gt;subxcnt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="cm"&gt;/* # of xact IDs in subxip[] */&lt;/span&gt;
    &lt;span class="n"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;suboverflowed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="cm"&gt;/* has the subxip array overflowed? */&lt;/span&gt;

    &lt;span class="n"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;takenDuringRecovery&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="cm"&gt;/* recovery-shaped snapshot? */&lt;/span&gt;
    &lt;span class="n"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;copied&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;      &lt;span class="cm"&gt;/* false if it's a static snapshot */&lt;/span&gt;

    &lt;span class="n"&gt;CommandId&lt;/span&gt; &lt;span class="n"&gt;curcid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;      &lt;span class="cm"&gt;/* in my xact, CID &amp;lt; curcid are visible */&lt;/span&gt;

    &lt;span class="n"&gt;uint32&lt;/span&gt; &lt;span class="n"&gt;speculativeToken&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;uint32&lt;/span&gt; &lt;span class="n"&gt;active_count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="cm"&gt;/* refcount on ActiveSnapshot stack */&lt;/span&gt;
    &lt;span class="n"&gt;uint32&lt;/span&gt; &lt;span class="n"&gt;regd_count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="cm"&gt;/* refcount on RegisteredSnapshots */&lt;/span&gt;
    &lt;span class="n"&gt;pairingheap_node&lt;/span&gt; &lt;span class="n"&gt;ph_node&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="cm"&gt;/* link in the RegisteredSnapshots heap */&lt;/span&gt;

    &lt;span class="n"&gt;TimestampTz&lt;/span&gt; &lt;span class="n"&gt;whenTaken&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;    &lt;span class="cm"&gt;/* timestamp when snapshot was taken */&lt;/span&gt;
    &lt;span class="n"&gt;XLogRecPtr&lt;/span&gt; &lt;span class="n"&gt;lsn&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;      &lt;span class="cm"&gt;/* position in the WAL stream when taken */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;SnapshotData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Transactions with IDs less than &lt;code&gt;xmin&lt;/code&gt; are visible; those with IDs greater than or equal to &lt;code&gt;xmax&lt;/code&gt; are invisible. Transactions between &lt;code&gt;xmin&lt;/code&gt; and &lt;code&gt;xmax&lt;/code&gt; might still be active, requiring an array (&lt;code&gt;xip&lt;/code&gt;) to track them. If found in &lt;code&gt;xip&lt;/code&gt;, the transaction is ongoing and invisible.&lt;/p&gt;

&lt;p&gt;When fetching data, it first checks the snapshot to see if the transaction is complete. If not, it's invisible. If complete, it checks whether it was committed or aborted by querying the commit log (CLOG). For performance, PostgreSQL also employs tuple header flags to reduce CLOG queries.&lt;/p&gt;

&lt;h5&gt;
  
  
  3.2 Commit/Abort
&lt;/h5&gt;

&lt;p&gt;In PostgreSQL, a transaction can end in one of two states: Commit or Abort:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Commit:&lt;/strong&gt; Writes to the Write-Ahead Log (WAL) and CLOG on commit. Post-commit, the transaction's changes are visible to others.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Abort:&lt;/strong&gt; Writes to WAL and CLOG on abort. Post-abort, the transaction's changes remain invisible to others.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>programming</category>
      <category>sql</category>
      <category>database</category>
      <category>sqlserver</category>
    </item>
    <item>
      <title>How to Implement Batch Message Consumption with RocketMQ in Spring Boot</title>
      <dc:creator>EVan Wilson</dc:creator>
      <pubDate>Fri, 13 Sep 2024 13:27:07 +0000</pubDate>
      <link>https://dev.to/wilson_evan_1efa5910f8855/how-to-implement-batch-message-consumption-with-rocketmq-in-spring-boot-6gi</link>
      <guid>https://dev.to/wilson_evan_1efa5910f8855/how-to-implement-batch-message-consumption-with-rocketmq-in-spring-boot-6gi</guid>
      <description>&lt;h4&gt;
  
  
  1. Adding Dependencies
&lt;/h4&gt;

&lt;p&gt;First, add the necessary dependencies to your &lt;code&gt;pom.xml&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- RocketMQ Spring Boot dependency for Spring Boot 3 --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.rocketmq&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;rocketmq-spring-boot-starter&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.3.1&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;exclusions&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;exclusion&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.rocketmq&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;rocketmq-client&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/exclusion&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/exclusions&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- Dependency compatible with MQ cluster version 5.3.0 --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;org.apache.rocketmq&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;rocketmq-client&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;5.3.0&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. Configuration File &lt;code&gt;bootstrap.yaml&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;Configure your RocketMQ settings in the &lt;code&gt;bootstrap.yaml&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;rocketmq&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name-server&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;192.168.1.1:9876;192.168.1.2:9876;192.168.1.3:9876&lt;/span&gt; &lt;span class="c1"&gt;# Replace with actual NameServer addresses&lt;/span&gt;
  &lt;span class="na"&gt;consumer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;group&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;consume-group-test&lt;/span&gt;
    &lt;span class="na"&gt;access-key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;access&lt;/span&gt; &lt;span class="c1"&gt;# Configure if ACL is used&lt;/span&gt;
    &lt;span class="na"&gt;secret-key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;secret&lt;/span&gt;
    &lt;span class="na"&gt;consume-message-batch-max-size&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50&lt;/span&gt;  &lt;span class="c1"&gt;# Max messages per batch&lt;/span&gt;
    &lt;span class="na"&gt;pull-batch-size&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;  &lt;span class="c1"&gt;# Max messages pulled from Broker&lt;/span&gt;
  &lt;span class="na"&gt;topics&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;project&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;group-topic-1"&lt;/span&gt;
  &lt;span class="na"&gt;groups&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;project&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;consume-group-1"&lt;/span&gt;  &lt;span class="c1"&gt;# Use different groups for different business processes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. Configuration Class &lt;code&gt;MqConfigProperties&lt;/code&gt;
&lt;/h4&gt;

&lt;p&gt;Create the configuration class &lt;code&gt;MqConfigProperties&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.apache.rocketmq.spring.autoconfigure.RocketMQProperties&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.beans.factory.annotation.Autowired&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.boot.context.properties.ConfigurationProperties&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.stereotype.Component&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;lombok.Data&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.io.Serializable&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * RocketMQ Configuration Class
 */&lt;/span&gt;
&lt;span class="nd"&gt;@Data&lt;/span&gt;
&lt;span class="nd"&gt;@Component&lt;/span&gt;
&lt;span class="nd"&gt;@ConfigurationProperties&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prefix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"rocketmq"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MqConfigProperties&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Serializable&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;serialVersionUID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1L&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Autowired&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;RocketMQProperties&lt;/span&gt; &lt;span class="n"&gt;rocketMQProperties&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;TopicProperties&lt;/span&gt; &lt;span class="n"&gt;topics&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;GroupProperties&lt;/span&gt; &lt;span class="n"&gt;groups&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="cm"&gt;/**
     * Topic Configuration Class
     */&lt;/span&gt;
    &lt;span class="nd"&gt;@Data&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TopicProperties&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Serializable&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;serialVersionUID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1L&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="cm"&gt;/**
     * Consumer Group Configuration Class
     */&lt;/span&gt;
    &lt;span class="nd"&gt;@Data&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GroupProperties&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Serializable&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;serialVersionUID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1L&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  4. Implementing the Consumer Code
&lt;/h4&gt;

&lt;p&gt;Create the consumer class &lt;code&gt;UserConsumer&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.alibaba.fastjson2.JSONObject&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.apache.rocketmq.client.consumer.DefaultMQPushConsumer&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.apache.rocketmq.client.consumer.rebalance.AllocateMessageQueueAveragely&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.apache.rocketmq.common.consumer.ConsumeFromWhere&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.apache.rocketmq.common.message.MessageExt&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.apache.rocketmq.remoting.RPCHook&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.apache.rocketmq.spring.support.RocketMQUtil&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.context.ApplicationContext&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.context.SmartLifecycle&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.springframework.stereotype.Component&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;lombok.extern.slf4j.Slf4j&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;javax.annotation.Resource&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.List&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Batch Consumer Implementation
 */&lt;/span&gt;
&lt;span class="nd"&gt;@Component&lt;/span&gt;
&lt;span class="nd"&gt;@Slf4j&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserConsumer&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;SmartLifecycle&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Resource&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;MqConfigProperties&lt;/span&gt; &lt;span class="n"&gt;mqConfigProperties&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Resource&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;ApplicationContext&lt;/span&gt; &lt;span class="n"&gt;applicationContext&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;volatile&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;running&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;DefaultMQPushConsumer&lt;/span&gt; &lt;span class="n"&gt;consumer&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;start&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isRunning&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;IllegalStateException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Consumer is already running"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;initConsumer&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;setRunning&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"UserConsumer started successfully."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;stop&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;isRunning&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;consumer&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;consumer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;shutdown&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;setRunning&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"UserConsumer stopped."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;isRunning&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;running&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setRunning&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;running&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;running&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;running&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;initConsumer&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mqConfigProperties&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getTopics&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getProject&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mqConfigProperties&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getGroups&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getProject&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;nameServer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mqConfigProperties&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getRocketMQProperties&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getNameServer&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;accessKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mqConfigProperties&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getRocketMQProperties&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getConsumer&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getAccessKey&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;secretKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mqConfigProperties&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getRocketMQProperties&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getConsumer&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getSecretKey&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="nc"&gt;RPCHook&lt;/span&gt; &lt;span class="n"&gt;rpcHook&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RocketMQUtil&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getRPCHookByAkSk&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;applicationContext&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getEnvironment&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;accessKey&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;secretKey&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;consumer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rpcHook&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
                &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;DefaultMQPushConsumer&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rpcHook&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AllocateMessageQueueAveragely&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
                &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;DefaultMQPushConsumer&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;consumer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setNamesrvAddr&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nameServer&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;consumer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setConsumeFromWhere&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ConsumeFromWhere&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CONSUME_FROM_LAST_OFFSET&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;consumer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setConsumeMessageBatchMaxSize&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Set the batch size for consumption&lt;/span&gt;
        &lt;span class="n"&gt;consumer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;subscribe&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"*"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;consumer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setMessageListener&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;MessageListenerConcurrently&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nd"&gt;@Override&lt;/span&gt;
            &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;ConsumeConcurrentlyStatus&lt;/span&gt; &lt;span class="nf"&gt;consumeMessage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;MessageExt&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;msgs&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;ConsumeConcurrentlyContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Received {} messages"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msgs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
                &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MessageExt&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;msgs&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBody&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
                    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Processing message: {}"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                    &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;JSONObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parseObject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                    &lt;span class="n"&gt;processUser&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="o"&gt;}&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;ConsumeConcurrentlyStatus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CONSUME_SUCCESS&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;});&lt;/span&gt;

        &lt;span class="n"&gt;consumer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;start&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"UserConsumer initialized with topic [{}] and group [{}]."&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;processUser&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;info&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Processing user with ID: {}"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getId&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
        &lt;span class="c1"&gt;// Handle user-related business logic&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  5. Producer Example Code
&lt;/h4&gt;

&lt;p&gt;To produce batch messages, you can use the following &lt;code&gt;UserProducer&lt;/code&gt; class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.apache.rocketmq.client.producer.DefaultMQProducer&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.apache.rocketmq.common.message.Message&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.ArrayList&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.List&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserProducer&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="nc"&gt;DefaultMQProducer&lt;/span&gt; &lt;span class="n"&gt;producer&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;sendBatchMessages&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Message&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ArrayList&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;add&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Message&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;JSONObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toJSONString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;getBytes&lt;/span&gt;&lt;span class="o"&gt;()));&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;producer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;send&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error sending batch messages"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  6. Additional Optimization Suggestions
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Performance Optimization:&lt;/strong&gt; You can adjust the size of the consumer thread pool. By default, it's set to &lt;code&gt;consumeThreadMin=20&lt;/code&gt; and &lt;code&gt;consumeThreadMax=20&lt;/code&gt;. In high-concurrency scenarios, increasing the thread pool size can enhance performance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Error Handling:&lt;/strong&gt; When consumption fails, be cautious with &lt;code&gt;RECONSUME_LATER&lt;/code&gt; to avoid infinite retry loops. Set a maximum retry count based on your business requirements.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tenant Isolation:&lt;/strong&gt; Use different groups for different business modules to avoid consuming data from the wrong group. This is especially crucial in production environments.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>beginners</category>
      <category>devops</category>
      <category>java</category>
    </item>
    <item>
      <title>How to Correct Yum Baseurl Issues on CentOS 7</title>
      <dc:creator>EVan Wilson</dc:creator>
      <pubDate>Thu, 12 Sep 2024 13:37:19 +0000</pubDate>
      <link>https://dev.to/wilson_evan_1efa5910f8855/how-to-correct-yum-baseurl-issues-on-centos-7-48ho</link>
      <guid>https://dev.to/wilson_evan_1efa5910f8855/how-to-correct-yum-baseurl-issues-on-centos-7-48ho</guid>
      <description>&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;_CentOS 7 Yum Error: Cannot Find a Valid Baseurl for Repo:base/7/x86_64_
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hey folks,&lt;/p&gt;

&lt;p&gt;Encountering the error &lt;code&gt;cannot find a valid baseurl for repo:base/7/x86_64&lt;/code&gt; can be quite frustrating, especially when you're trying to get things done on CentOS 7. This issue generally occurs because Yum can't find or access the repository URLs it needs. Let's break down a few ways to troubleshoot and fix this problem, step by step.&lt;/p&gt;

&lt;h4&gt;
  
  
  Error Explanation
&lt;/h4&gt;

&lt;p&gt;This error usually happens when Yum can't locate or access repository sources, making it unable to function properly. It's common on CentOS 7 and can typically be resolved by checking a few things like network connectivity, DNS settings, and Yum repository configurations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step-by-Step Solutions to Fix the Error
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Method 1: Check Network Connectivity
&lt;/h4&gt;

&lt;p&gt;First things first, make sure your system is connected to the internet because Yum needs to reach remote repositories to download packages.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Verify Network Connection&lt;/strong&gt;
You can check if your system can access external websites by running:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   ping &lt;span class="nt"&gt;-c&lt;/span&gt; 4 google.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If it doesn't ping successfully, you might have a network configuration issue. You can restart the network service with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart network
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Method 2: Check DNS Settings
&lt;/h4&gt;

&lt;p&gt;If your network connection is fine but you still can't access repositories, the issue might be with your DNS settings.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Update DNS Configuration&lt;/strong&gt;
Edit the &lt;code&gt;/etc/resolv.conf&lt;/code&gt; file to ensure it contains valid DNS servers like Google's public DNS:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/resolv.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the following lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   nameserver 8.8.8.8
   nameserver 8.8.4.4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save the file and exit.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Check Domain Name Resolution&lt;/strong&gt;
Run another ping test to verify:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   ping &lt;span class="nt"&gt;-c&lt;/span&gt; 4 google.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Method 3: Check Yum Repository Configuration
&lt;/h4&gt;

&lt;p&gt;If the network connection and DNS settings are fine, the problem might be with your Yum repository configuration.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Update Yum Repository Sources&lt;/strong&gt;
Back up your current Yum config files:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo cp&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; /etc/yum.repos.d /etc/yum.repos.d.backup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Edit or replace the repository configuration files. For example, open &lt;code&gt;/etc/yum.repos.d/CentOS-Base.repo&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/yum.repos.d/CentOS-Base.repo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ensure the &lt;code&gt;baseurl&lt;/code&gt; and &lt;code&gt;gpgcheck&lt;/code&gt; settings are correct. You can manually edit this file or use a reliable mirror source.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: Using Official CentOS Mirror Config&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;   &lt;span class="nn"&gt;[base]&lt;/span&gt;
   &lt;span class="py"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;CentOS-$releasever - Base&lt;/span&gt;
   &lt;span class="py"&gt;baseurl&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;http://mirror.centos.org/centos/$releasever/os/$basearch/&lt;/span&gt;
   &lt;span class="py"&gt;gpgcheck&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;1&lt;/span&gt;
   &lt;span class="py"&gt;gpgkey&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-7&lt;/span&gt;

   &lt;span class="nn"&gt;[updates]&lt;/span&gt;
   &lt;span class="py"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;CentOS-$releasever - Updates&lt;/span&gt;
   &lt;span class="py"&gt;baseurl&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;http://mirror.centos.org/centos/$releasever/updates/$basearch/&lt;/span&gt;
   &lt;span class="py"&gt;gpgcheck&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;1&lt;/span&gt;
   &lt;span class="py"&gt;gpgkey&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-7&lt;/span&gt;

   &lt;span class="nn"&gt;[extras]&lt;/span&gt;
   &lt;span class="py"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;CentOS-$releasever - Extras&lt;/span&gt;
   &lt;span class="py"&gt;baseurl&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;http://mirror.centos.org/centos/$releasever/extras/$basearch/&lt;/span&gt;
   &lt;span class="py"&gt;gpgcheck&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;1&lt;/span&gt;
   &lt;span class="py"&gt;gpgkey&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-7&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save and exit the file.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Clear and Rebuild Yum Cache&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;yum clean all
   &lt;span class="nb"&gt;sudo &lt;/span&gt;yum makecache
   &lt;span class="nb"&gt;sudo &lt;/span&gt;yum update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;cannot find a valid baseurl for repo:base/7/x86_64&lt;/code&gt; error is often due to issues with network connectivity, DNS settings, or Yum repository configuration. By checking and fixing these aspects, or by using reliable mirror sources , you can solve this problem efficiently. Hope this guide helps you get Yum back up and running smoothly. If you have any questions or further issues, feel free to drop a comment!&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>beginners</category>
      <category>python</category>
      <category>devops</category>
    </item>
    <item>
      <title>Spring Boot: How to Solve Cross-Origin Issues</title>
      <dc:creator>EVan Wilson</dc:creator>
      <pubDate>Wed, 11 Sep 2024 13:20:05 +0000</pubDate>
      <link>https://dev.to/wilson_evan_1efa5910f8855/spring-boot-how-to-solve-cross-origin-issues-4non</link>
      <guid>https://dev.to/wilson_evan_1efa5910f8855/spring-boot-how-to-solve-cross-origin-issues-4non</guid>
      <description>&lt;h2&gt;
  
  
  Cross-Origin Issue Description
&lt;/h2&gt;

&lt;p&gt;You might encounter the following error message:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This error indicates that a request to a certain address has been blocked by the CORS protocol because the &lt;code&gt;Access-Control-Allow-Origin&lt;/code&gt; header is missing from the resource.&lt;/p&gt;

&lt;h2&gt;
  
  
  Analyzing Cross-Origin Issues
&lt;/h2&gt;

&lt;p&gt;The root cause of cross-origin issues is that browsers, for security reasons, restrict access to resources outside the current site.&lt;/p&gt;

&lt;p&gt;For example, consider a website hosted at &lt;code&gt;http://127.0.0.1:8080/&lt;/code&gt; with a certain page. If you access resources from the same site, there are no restrictions. But if you try to access resources from a different site (e.g., &lt;code&gt;http://127.0.0.1:8081&lt;/code&gt;), the browser will block the request.&lt;/p&gt;

&lt;p&gt;Note: We consider protocol, domain, and port as part of defining a "same-origin."&lt;/p&gt;

&lt;p&gt;Elements with a &lt;code&gt;src&lt;/code&gt; attribute, like &lt;code&gt;img&lt;/code&gt; and &lt;code&gt;script&lt;/code&gt; tags, are not subject to this restriction.&lt;/p&gt;

&lt;p&gt;Historically, when front-end and back-end were not separate, pages and request interfaces existed under the same domain and port. Browsers would then allow requests from a page hosted at one domain to request resources from the same domain.&lt;/p&gt;

&lt;p&gt;For example, &lt;code&gt;http://127.0.0.1:8080/index.html&lt;/code&gt; can freely request &lt;code&gt;http://127.0.0.1:8080/a/b/c/userLit&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Nowadays, with the front-end and back-end separated into different applications, this isn't allowed and will trigger CORS issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Origin and Cross-Origin?
&lt;/h2&gt;

&lt;p&gt;Origin (or source) consists of the protocol, domain, and port number.&lt;/p&gt;

&lt;p&gt;A URL is composed of protocol, domain, port, and path. Two URLs are considered "same-origin" if their protocol, domain, and port are all identical. Any difference in any of these three elements constitutes a cross-origin request.&lt;/p&gt;

&lt;p&gt;Consider cross-origin comparisons for &lt;code&gt;https://www.baidu.com/index.html&lt;/code&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;URL&lt;/th&gt;
&lt;th&gt;Cross-Origin&lt;/th&gt;
&lt;th&gt;Reason&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.baidu.com/more/index.html" rel="noopener noreferrer"&gt;https://www.baidu.com/more/index.html&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Same protocol, domain, and port&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://map.baidu.com/" rel="noopener noreferrer"&gt;https://map.baidu.com/&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Different domain&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://www.baidu.com/index.html" rel="noopener noreferrer"&gt;http://www.baidu.com/index.html&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Different protocol&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.baidu.com:81/index.html" rel="noopener noreferrer"&gt;https://www.baidu.com:81/index.html&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Different port&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  What is the Same-Origin Policy?
&lt;/h2&gt;

&lt;p&gt;The Same-Origin Policy is a fundamental browser security feature. Without it, the normal functionality of browsers could be at risk. Web architecture heavily depends on this policy, and browsers implement it to ensure security.&lt;/p&gt;

&lt;p&gt;The Same-Origin Policy includes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;DOM Same-Origin Policy&lt;/strong&gt;: Prevents DOM manipulation of different origin pages. Applies mainly to cross-origin &lt;code&gt;iframe&lt;/code&gt; scenarios where different domains' &lt;code&gt;iframes&lt;/code&gt; can't access each other.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;XMLHttpRequest Same-Origin Policy&lt;/strong&gt;: Prohibits HTTP requests to different origins using XHR objects.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Solving Cross-Origin Issues in Spring Boot
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Creating a Filter to Handle CORS
&lt;/h3&gt;

&lt;p&gt;In a project where the front-end and back-end are deployed separately, addressing CORS is crucial. Cookies are used to store user login information, and Spring interceptors manage permissions. Issues arise when the interceptor and CORS are processed in the wrong order, causing a CORS error.&lt;/p&gt;

&lt;p&gt;An HTTP request first goes through the filter before reaching the servlet and then the interceptor. To ensure CORS processing occurs before authorization interception, we can place the CORS configuration in a filter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Configuration&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CorsConfig&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Bean&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;CorsFilter&lt;/span&gt; &lt;span class="nf"&gt;corsFilter&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;CorsConfiguration&lt;/span&gt; &lt;span class="n"&gt;corsConfiguration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CorsConfiguration&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;corsConfiguration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addAllowedOrigin&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"*"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;corsConfiguration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addAllowedHeader&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"*"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;corsConfiguration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addAllowedMethod&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"*"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;corsConfiguration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setAllowCredentials&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="nc"&gt;UrlBasedCorsConfigurationSource&lt;/span&gt; &lt;span class="n"&gt;urlBasedCorsConfigurationSource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;UrlBasedCorsConfigurationSource&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;urlBasedCorsConfigurationSource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;registerCorsConfiguration&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/**"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;corsConfiguration&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;CorsFilter&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;urlBasedCorsConfigurationSource&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Configuring CORS in WebMvcConfigurer
&lt;/h3&gt;

&lt;p&gt;While JSONP can address cross-origin issues on the front-end, it only supports GET requests, which is limiting in RESTful applications. Instead, you can handle cross-origin requests with Cross-Origin Resource Sharing (CORS) on the back-end. This solution is not unique to Spring Boot and has been used in traditional SSM frameworks. You configure it by implementing the &lt;code&gt;WebMvcConfigurer&lt;/code&gt; interface and overriding the &lt;code&gt;addCorsMappings&lt;/code&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Configuration&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CorsConfig&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;WebMvcConfigurer&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;addCorsMappings&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;CorsRegistry&lt;/span&gt; &lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;registry&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/**"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;allowedOrigins&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"*"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;allowCredentials&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;allowedMethods&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"GET"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"POST"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"PUT"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"DELETE"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"OPTIONS"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;maxAge&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3600&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Configuring CORS in Controller
&lt;/h3&gt;

&lt;p&gt;You can enable CORS for specific controller methods by adding the &lt;code&gt;@CrossOrigin&lt;/code&gt; annotation to the &lt;code&gt;@RequestMapping&lt;/code&gt; annotation. By default, &lt;code&gt;@CrossOrigin&lt;/code&gt; allows all origins and HTTP methods specified in &lt;code&gt;@RequestMapping&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@RestController&lt;/span&gt;
&lt;span class="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/account"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AccountController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@CrossOrigin&lt;/span&gt;
    &lt;span class="nd"&gt;@GetMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/{id}"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Account&lt;/span&gt; &lt;span class="nf"&gt;retrieve&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathVariable&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@DeleteMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/{id}"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathVariable&lt;/span&gt; &lt;span class="nc"&gt;Long&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Understanding @CrossOrigin Parameters：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;@CrossOrigin&lt;/code&gt; without parameters allows all URLs to access.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@CrossOrigin(origins = "http://127.0.0.1:8080")&lt;/code&gt; restricts access to the specified URL.&lt;/li&gt;
&lt;li&gt;This annotation can be used on classes or methods.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;value&lt;/code&gt; or &lt;code&gt;origins&lt;/code&gt; attribute specifies allowed URLs.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;maxAge&lt;/code&gt; indicates the maximum age in seconds for the preflight request cache.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;allowCredentials&lt;/code&gt; indicates if credentials (cookies) are allowed. Default is &lt;code&gt;false&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;allowedHeaders&lt;/code&gt; specifies allowed request headers.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;methods&lt;/code&gt; specifies allowed request methods, default being GET, POST, HEAD.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Reasons @CrossOrigin Might Not Work
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Spring MVC version must be 4.2 or higher to support &lt;code&gt;@CrossOrigin&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Incorrect requests might appear as cross-origin issues due to improper server response.&lt;/li&gt;
&lt;li&gt;If adding &lt;code&gt;@CrossOrigin&lt;/code&gt; above the &lt;code&gt;Controller&lt;/code&gt; annotation still results in issues, one possible fix is to specify the HTTP methods in &lt;code&gt;@RequestMapping&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@CrossOrigin&lt;/span&gt;
&lt;span class="nd"&gt;@RestController&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PersonController&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nd"&gt;@RequestMapping&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RequestMethod&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;GET&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// some code&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>programming</category>
      <category>webdev</category>
      <category>java</category>
      <category>coding</category>
    </item>
  </channel>
</rss>
