<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>공부하는 개발자 핑구  </title>
    <link>https://developer-ping9.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Sun, 17 May 2026 00:10:37 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>DevPing9_</managingEditor>
    <image>
      <title>공부하는 개발자 핑구  </title>
      <url>https://tistory1.daumcdn.net/tistory/4145113/attach/fd80c371230c417c9888fab889438ed2</url>
      <link>https://developer-ping9.tistory.com</link>
    </image>
    <item>
      <title>`@Volatile` 이해하기</title>
      <link>https://developer-ping9.tistory.com/686</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;@Volatile
private var something: Something&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동료분이 해당 코드에 리뷰를 해주었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div style=&quot;margin: 0.5rem 0px; border: 2px solid #A9BCF5; border-radius: 8px; background: #CED8F6; padding: 0.5rem 0.5rem 0.5rem 2rem;&quot;&gt;&lt;span style=&quot;background-color: #e6f5ff; color: #333333; text-align: center;&quot;&gt;&lt;/span&gt;&lt;b&gt;@Volatile&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;은&amp;nbsp; ThreadLocal 에 저장하는 키워드로 알고 있는데, Webflux + 코루틴 환경에서 문제가 없을까요?&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;@Volatile &lt;/b&gt;은 CPU 캐시가 아닌 메인 메모리를 보게하는 명령어라고만 알고 있었다.&lt;br /&gt;문제가 없어보이지만 혹시 내가 아는게 다르지 않을까 싶어 여러 문서를 뒤져보고 알게 된 지식을 정리하고자 한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;# Volatile&lt;/b&gt;&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;CPU 캐시는 &lt;b&gt;ThreadLocal(JVM Heap 에 저장되는 자료구조)&lt;/b&gt; 에 저장되는 값이 아닌 OS 의 CPU Core 에 저장되는 캐시이다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;@Volatile&lt;/b&gt;&amp;nbsp;키워드는 메모리 모델 상의 happens-before 관계만 정의한다. 즉, JVM 이 어떻게 이를 구현할지는 자유이다.&lt;br /&gt;이때 말하는 메모리는 Java Thread 의 ThreadLocal 이 아닌 &lt;b&gt;JMM&lt;/b&gt;&amp;nbsp;을 뜻한다.&lt;br /&gt;&lt;b&gt;@Volatile &lt;/b&gt;에 관해 CPU 캐시가 아닌 메인 메모리를 보게한다는 설명은 교육적 예시일 뿐이다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html?utm_source=chatgpt.com#volatile:~:text=change%20final%20fields.-,What%20does%20volatile%20do%3F,-Volatile%20fields%20are&quot;&gt;Volatile 설명 Highlight Link&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html&quot;&gt;OrcleDocs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결론적으로&amp;nbsp;&lt;b&gt;@Volatile &lt;/b&gt;은 JMM 규칙(visibility/ordering 를 보장)이며, JVM이 이를 지키기 위해 메모리 장벽 같은 기법으로 보장한다. 어떤 방식으로 보장할 것인지는 제한하지 않고 있다. 실제 캐시/메모리 동작은 JVM 구현과 CPU 아키텍처에 의존한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;# Volatile 이 보장하는 것&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. visibility&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;한 스레드가 값을 쓰면 다른 스레드가 항상 최신 값을 보게 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. ordering&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이전의 모든 쓰기가 이후의 모든 읽기보다 먼저 보임&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;# @Volatile vs ThreadLocal&lt;/b&gt;&lt;/h3&gt;
&lt;table data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;구분&lt;/th&gt;
&lt;th&gt;@Volatile&lt;/th&gt;
&lt;th&gt;ThreadLocal&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;공유 여부&lt;/td&gt;
&lt;td&gt;공유됨&lt;/td&gt;
&lt;td&gt;스레드별&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;가시성&lt;/td&gt;
&lt;td&gt;보장&lt;/td&gt;
&lt;td&gt;의미 없음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;스레드 이동&lt;/td&gt;
&lt;td&gt;안전&lt;/td&gt;
&lt;td&gt;깨짐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WebFlux&lt;/td&gt;
&lt;td&gt;사용 가능&lt;/td&gt;
&lt;td&gt;위험&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</description>
      <category>프로그래밍 언어/Kotlin</category>
      <author>DevPing9_</author>
      <guid isPermaLink="true">https://developer-ping9.tistory.com/686</guid>
      <comments>https://developer-ping9.tistory.com/686#entry686comment</comments>
      <pubDate>Wed, 31 Dec 2025 16:05:09 +0900</pubDate>
    </item>
    <item>
      <title>gRPC Unary 와 REST API 속도 차이 (1) - 직렬화, 역직렬화</title>
      <link>https://developer-ping9.tistory.com/685</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;직렬화 포맷 (Protocol Buffers vs JSON)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조금만 검색해보아도 gRPC 는 데이터 직렬화를 바이너리로 하니 더 빠르다는 정보를 찾을 수 있다.&lt;br /&gt;JSON 도 직렬화하면 바이너리로 변환되는데 무슨 차이점이 있을까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서, 정확히 어떤 방식으로 데이터가 직렬화 되기에 페이로드가 짧아지는지 알아보자.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;JSON 직렬화&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JSON 문자열을 바이너리로 바꾼다는 건, 해당 문자열을 UTF-8 바이트 시퀀스로 변환하는 것을 말한다.&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;name&quot;: &quot;Alice&quot;,
  &quot;age&quot;: 30
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 데이터를 바이트 시퀀스(16진수)로 직렬화하면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;7b 22 6e 61 6d 65 22 3a 22 41 6c 69 63 65 22 2c 22 61 67 65 22 3a 33 30 7d&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;총 25 bytes&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 153px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 13.6822%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;JSON 문자열&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 52.9845%; height: 17px;&quot;&gt;&lt;b&gt;바이트&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 13.6822%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;{&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 52.9845%; height: 17px;&quot;&gt;7b&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 13.6822%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;&quot;name&quot;:&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 52.9845%; height: 17px;&quot;&gt;22 6e 61 6d 65 22 3a&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 13.6822%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;&quot;Alice&quot;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 52.9845%; height: 17px;&quot;&gt;22 41 6c 69 63 65 22&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 13.6822%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;,&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 52.9845%; height: 17px;&quot;&gt;2c&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 13.6822%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;&quot;age&quot;:&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 52.9845%; height: 17px;&quot;&gt;22 61 67 65 22 3a&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 13.6822%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;30&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 52.9845%; height: 17px;&quot;&gt;33 30&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 13.6822%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;}&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 52.9845%; height: 17px;&quot;&gt;7d&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Protobuf 직렬화&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;미리 정의된 스키마를 기반으로 필드 번호와 타입, 값만 이진 규격에 맞게 바이트 시퀀스로 변환한다.&lt;/p&gt;
&lt;pre class=&quot;protobuf&quot;&gt;&lt;code&gt;message Person {
  string name = 1;
  int32 age = 2;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 데이터를 바이트 시퀀스(16진수)로 직렬화하면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;0a 05 41 6c 69 63 65 10 1e&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;총 9 bytes&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 87px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 38.4884%; height: 19px; text-align: center;&quot;&gt;&lt;b&gt;Protobuf 직렬화&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 61.5116%; height: 19px;&quot;&gt;&lt;b&gt;바이트&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 38.4884%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;field 1 (name), wire type 2&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 61.5116%; height: 17px;&quot;&gt;0a&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 38.4884%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;문자열 길이 5&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 61.5116%; height: 17px;&quot;&gt;05&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 38.4884%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;'A' 'l' 'i' 'c' 'e' (ASCII)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 61.5116%; height: 17px;&quot;&gt;41 6c 69 63 65&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 38.4884%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;field 2 (age), wire type 0&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 61.5116%; height: 17px;&quot;&gt;10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 38.4884%; text-align: center;&quot;&gt;&lt;b&gt;숫자 30 (varint 인코딩)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 61.5116%;&quot;&gt;1e&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;직렬화 비교&lt;/b&gt;&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 141px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 21.2791%; height: 19px; text-align: center;&quot;&gt;&lt;b&gt;JSON 문자열&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 27.3256%; height: 19px;&quot;&gt;바이트&lt;/td&gt;
&lt;td style=&quot;width: 26.3953%; height: 19px; text-align: center;&quot;&gt;&lt;b&gt;Protobuf 직렬화&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 19px;&quot;&gt;바이트&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 21.2791%; height: 18px; text-align: center;&quot;&gt;&lt;b&gt;{&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 27.3256%; height: 18px;&quot;&gt;7b&lt;/td&gt;
&lt;td style=&quot;width: 26.3953%; height: 18px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 18px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 21.2791%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;&quot;name&quot;:&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 27.3256%; height: 17px;&quot;&gt;22 6e 61 6d 65 22 3a&lt;/td&gt;
&lt;td style=&quot;width: 26.3953%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;field 1 (name), wire type 2&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px;&quot;&gt;0a&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 21.2791%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;&quot;Alice&quot;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 27.3256%; height: 17px;&quot;&gt;22 41 6c 69 63 65 22&lt;/td&gt;
&lt;td style=&quot;width: 26.3953%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;'A' 'l' 'i' 'c' 'e' (ASCII)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px;&quot;&gt;41 6c 69 63 65&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 21.2791%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;,&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 27.3256%; height: 17px;&quot;&gt;2c&lt;/td&gt;
&lt;td style=&quot;width: 26.3953%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 21.2791%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;&quot;age&quot;:&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 27.3256%; height: 17px;&quot;&gt;22 61 67 65 22 3a&lt;/td&gt;
&lt;td style=&quot;width: 26.3953%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;field 2 (age), wire type 0&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px;&quot;&gt;10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 21.2791%; height: 19px; text-align: center;&quot;&gt;&lt;b&gt;30&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 27.3256%; height: 19px;&quot;&gt;33 30&lt;/td&gt;
&lt;td style=&quot;width: 26.3953%; height: 19px; text-align: center;&quot;&gt;&lt;b&gt;숫자 30 (varint 인코딩)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 19px;&quot;&gt;1e&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 21.2791%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;}&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 27.3256%; height: 17px;&quot;&gt;7d&lt;/td&gt;
&lt;td style=&quot;width: 26.3953%; height: 17px; text-align: center;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Back End/gRPC</category>
      <author>DevPing9_</author>
      <guid isPermaLink="true">https://developer-ping9.tistory.com/685</guid>
      <comments>https://developer-ping9.tistory.com/685#entry685comment</comments>
      <pubDate>Thu, 17 Jul 2025 10:13:54 +0900</pubDate>
    </item>
    <item>
      <title>[Network] DHCP 에 대해 정말 간략히 알아보자</title>
      <link>https://developer-ping9.tistory.com/679</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;DHCP(Dynamic Host Configuration Protocol)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;네트워크에 연결된 장치(클라이언트)에게&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;자동으로 IP 주소, 서브넷 마스크, 게이트웨이, DNS 서버 등 네트워크 설정 정보를 할당&lt;/b&gt;하는 프로토콜&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;과거에는 IP를 고정적으로 수동할당하였다. IP 충돌이나 고갈을 해결하기 위하여 나온 자동할당 프로토콜이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;DHCP 서버&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DHCP 서버는 주로 라우터에 위치한다.&amp;nbsp; 경우에 따라 전용 DHCP 서버를 개설하여 관리할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Network Basis</category>
      <author>DevPing9_</author>
      <guid isPermaLink="true">https://developer-ping9.tistory.com/679</guid>
      <comments>https://developer-ping9.tistory.com/679#entry679comment</comments>
      <pubDate>Sun, 26 Jan 2025 19:35:08 +0900</pubDate>
    </item>
    <item>
      <title>[Network] ARP 와 RARP (MAC 주소가 필요한 이유)</title>
      <link>https://developer-ping9.tistory.com/678</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;들어가기 전에&lt;/b&gt;&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 133px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;IP 주소&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;MAC 주소&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;정의&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;네트워크 상에서 논리적 식별자&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;하드웨어 네트워크 인터페이스의 물리적 주소&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;OSI 계층&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;3계층 (네트워크 계층)&lt;br /&gt;패킷 전달을 위해 사용&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;2계층 (데이터 링크 계층)&lt;br /&gt;프레임 전송을 위해 사용&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;목적&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;전 세계, 인터넷 통신&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;로컬 네트워크 내부 통신&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;변경 여부&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;네트워크에 따라 변경 가능&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;기본적으로 변경 불가능 (제조 시 할당)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;할당 방식&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;정적 또는 동적 (DHCP)&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;하드웨어에서 자동 할당&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;역할&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;장치의 논리적 위치 식별&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;로컬 네트워크 내 데이터 전송 식별&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;개요&lt;/b&gt;&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 12.2869%;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 43.2169%;&quot;&gt;ARP 와 RARP&lt;/td&gt;
&lt;td style=&quot;width: 44.4961%;&quot;&gt;NDP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 12.2869%;&quot;&gt;정의&lt;/td&gt;
&lt;td style=&quot;width: 87.713%; text-align: center;&quot; colspan=&quot;2&quot;&gt;IP 주소와 MAC 주소(장치의 물리적 주소)를 상호 변환하는 데 사용되는 프로토콜&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 12.2869%;&quot;&gt;사용범위&lt;/td&gt;
&lt;td style=&quot;width: 43.2169%; text-align: center;&quot;&gt;IPv4 네트워크&lt;/td&gt;
&lt;td style=&quot;width: 44.4961%; text-align: center;&quot;&gt;IPv6 네트워크&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;IP 로만 데이터를 전송할 수는 없나? MAC 주소를 왜 꼭 알아야하는가?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대부분의 네트워크 장치는&lt;b&gt; OSI 2계층&lt;/b&gt;에서 동작하며, 2계층의 PDU 인 &lt;b&gt;프레임&lt;/b&gt;을 전송하기 위하여 &lt;b&gt;MAC 주소&lt;/b&gt;가 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 스위치, WAP, NIC, 브릿지, 라우터등의 네트워크장치는 보통 1~3계층까지만 구현이 되어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;호스트 A&lt;/b&gt; 에서 &lt;b&gt;호스트 B&lt;/b&gt; 로 데이터를 전송한다고 가정하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;호스트 A&lt;/b&gt; 는 여러 네트워크 장치를 거쳐 최종적으로 &lt;b&gt;호스트 B&lt;/b&gt;에게 &lt;b&gt;1계층 비트신호&lt;/b&gt;로 데이터를 전달하게 될 것이고, &lt;b&gt;호스트 B&lt;/b&gt; 는 1계층 비트신호를 7계층까지 Decapsulation 하여 A가 보내고자 했던 애플리케이션 데이터(7계층)을 추출한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;비트신호&lt;/b&gt;(1계층)를 &lt;b&gt;프레임&lt;/b&gt;(2계층)으로 변환할 때 &lt;b&gt;MAC 주소&lt;/b&gt;가 필요하고, &lt;b&gt;프레임&lt;/b&gt;(2계층)을 &lt;b&gt;패킷&lt;/b&gt;(3계층)으로 변환할 때 &lt;b&gt;IP 주소&lt;/b&gt;가 필요하기 때문에 MAC 주소가 꼭 필요한 것이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;ARP&lt;b&gt;(Address Resolution Protocol)&lt;/b&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;정의:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;IP 주소를 MAC 주소로 변환&lt;/b&gt;하는데 사용되는 프로토콜&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;동작과정:
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;호스트 A가 특정 IP 주소에 데이터를 보내려면 해당 IP의 MAC 주소를 알아야 함&amp;nbsp;&lt;/li&gt;
&lt;li&gt;호스트 A는 네트워크 전체에 &lt;b&gt;ARP 요청(브로드캐스트) 패킷&lt;/b&gt;을 보냄.&lt;/li&gt;
&lt;li&gt;해당 IP를 가진 호스트 B가 자신의 MAC 주소를 포함한 &lt;b&gt;ARP 응답(유니캐스트) 패킷&lt;/b&gt;을 전송.&lt;/li&gt;
&lt;li&gt;호스트 A는 응답을 받고, IP-MAC 매핑 정보를 ARP 캐시(테이블)에 저장하여 이후에는 동일 요청을 반복하지 않음.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;종류:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;일반 ARP:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특정 IP의 MAC 주소를 찾기 위한 표준 ARP&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;GARP (Gratuitous ARP):
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;중복 IP 감지 또는 ARP 캐시 갱신을 위해 자신의 정보를 네트워크에 알리는 방식&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;프록시 ARP: &lt;a href=&quot;https://www.cisco.com/c/ko_kr/support/docs/ip/dynamic-address-allocation-resolution/13718-5.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;(시스코 Docs)&lt;/a&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;라우터가 다른 네트워크를 대신하여 응답 (라우터 설정에 있음)&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;공격 사례
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;ARP 스푸핑 공격&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;공격자가 가짜 MAC 주소로 응답하여 중간자 공격 수행&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;RARP (Reverse Address Resolution Protocol)&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;정의:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;MAC 주소를 IP 주소로 변환&lt;/b&gt;하는데 사용되는 프로토콜&lt;/li&gt;
&lt;li&gt;자신의 IP를 알지 못할 경우 사용됨&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;동작과정:
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;클라이언트는 자신의 MAC 주소만 알고 있으며 IP 주소를 알지 못함.&lt;/li&gt;
&lt;li&gt;클라이언트는 네트워크에 &lt;b&gt;RARP 요청(브로드캐스트)&lt;/b&gt;을 보냄.&lt;/li&gt;
&lt;li&gt;네트워크의 RARP 서버가 요청을 수신하고, 클라이언트 MAC 주소와 일치하는 IP를 데이터베이스에서 조회.&lt;/li&gt;
&lt;li&gt;서버는 클라이언트에게 해당 MAC 주소에 대한 IP 주소를 응답(유니캐스트)으로 제공.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;단점 및 대체기술
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;RARP는 구성이 복잡하고, &lt;b&gt;IP 주소 할당을 위한 별도의 RARP 서버&lt;/b&gt;가 필요&lt;/li&gt;
&lt;li&gt;현재는 &lt;b&gt;DHCP&lt;/b&gt; (Dynamic Host Configuration Protocol)가 &lt;b&gt;RARP를 대체&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Network Basis</category>
      <author>DevPing9_</author>
      <guid isPermaLink="true">https://developer-ping9.tistory.com/678</guid>
      <comments>https://developer-ping9.tistory.com/678#entry678comment</comments>
      <pubDate>Sun, 26 Jan 2025 19:28:27 +0900</pubDate>
    </item>
    <item>
      <title>[Network] 전달한 패킷이 네트워크 장치가 수용할 수 있는 크기보다 크다면? (MTU, MSS, PMTUD)</title>
      <link>https://developer-ping9.tistory.com/676</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;들어가기전에&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OSI 7 Layer 의 2계층인&lt;b&gt; Data Link Layer&lt;/b&gt; 에서는 &lt;b&gt;Ethernet 프로토콜&lt;/b&gt;을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네트워크 장치들이 모두 &lt;b&gt;OSI 7계층 모델&lt;/b&gt;을 사용하는 것은 아니지만, &lt;b&gt;네트워크 통신&lt;/b&gt;을 수행하는 장치들은 &lt;b&gt;OSI 모델의 계층&lt;/b&gt; 중 일부를 사용하거나 참고한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;LAN(Local Area Network)&lt;/b&gt;을&amp;nbsp;구성하기 위해 &lt;b&gt;네트워크 카드(NIC), 스위치, 라우터, 허브, 액세스 포인트&lt;/b&gt; 등과 같은 &lt;b&gt;네트워크 장치&lt;/b&gt;가 사용되는데, 이러한 네트워크 장치를 통하여 데이터가 전달된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 전송할 데이터를 쪼개어 전송하게 되는데 쪼개어진 데이터를 *&lt;b&gt;패킷&lt;/b&gt;이라고 칭하며, 일반적으로 패킷의 크기가 클수록 &lt;b&gt;대역폭(Bandwidth)&lt;/b&gt;을 효과적으로 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;난 효율적인게 좋아!&lt;/b&gt;&lt;/h3&gt;
&lt;div style=&quot;margin: 2rem 0px; border-left: 4px solid #20C997; border-top-right-radius: 4px; border-bottom-right-radius: 4px; background: #F8F9FA; padding: 1rem 1rem 1rem 2rem; color: black;&quot;&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;우리집 인터넷은 1Gbps 라구!&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;굳이 데이터를 잘라서 보내서 오버헤드를 만들지 말고 한방에 보내버리면 완전 빠르겠구만!&lt;/p&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴퓨터에서 내보낸 패킷은 1GB지만, 다른 노드까지 향하는 길목에는 여러 &lt;b&gt;네트워크 장치&lt;/b&gt;들이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 &lt;b&gt;네트워크 장치&lt;/b&gt;들이 어느정도 크기의 데이터를 한번에 받을 수 있는지도 중요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 보통 대부분의 네트워크 장치들은 1500 바이트를 받을 수 있도록 만들어져 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;네트워크 장치가 &lt;b&gt;데이터 링크 계층(OSI 2계층)&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;에서 허용하는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;최대 페이로드 크기&lt;/b&gt;를 *&lt;b&gt;MTU&lt;/b&gt; 라고 하며, 네트워크 경로 상에 있는 아무 장치나 &lt;b&gt;MTU&lt;/b&gt; 보다 패킷이 크면 그 패킷은 분할될 수도 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;IPv6 은 분할을 허용하지 않으며, IPv4 는 헤더의 플래그 값에 따라 분할여부가 결정된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-01-18 오후 5.53.17.png&quot; data-origin-width=&quot;984&quot; data-origin-height=&quot;518&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0GhoX/btsLSzosffk/zBmoeWFd2JfrJFRlrSqp8K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0GhoX/btsLSzosffk/zBmoeWFd2JfrJFRlrSqp8K/img.png&quot; data-alt=&quot;IPv4 의 패킷분할 여부를 결정하는 Flags 헤더&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0GhoX/btsLSzosffk/zBmoeWFd2JfrJFRlrSqp8K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0GhoX%2FbtsLSzosffk%2FzBmoeWFd2JfrJFRlrSqp8K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;672&quot; height=&quot;354&quot; data-filename=&quot;스크린샷 2025-01-18 오후 5.53.17.png&quot; data-origin-width=&quot;984&quot; data-origin-height=&quot;518&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;IPv4 의 패킷분할 여부를 결정하는 Flags 헤더&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;어쩔 수 없네.. 1500바이트로 보내야겠다.&amp;nbsp;&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock floatLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;최대패킷의 크기.png&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;596&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EyVOw/btsLSp0riCQ/LHAR8zKMjCdje1fFXhW6QK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EyVOw/btsLSp0riCQ/LHAR8zKMjCdje1fFXhW6QK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EyVOw/btsLSp0riCQ/LHAR8zKMjCdje1fFXhW6QK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEyVOw%2FbtsLSp0riCQ%2FLHAR8zKMjCdje1fFXhW6QK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;396&quot; height=&quot;230&quot; data-filename=&quot;최대패킷의 크기.png&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;596&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;직접 1500 바이트로 데이터를 보내게되면 패킷이 도달하지 못하는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이유는 필자가 사용한 &lt;b&gt;bash&lt;/b&gt; 는 사용자를 위한 Application 이며, 때문에 ping 의 -s 옵션인 데이터의 크기는 보통 유저입장에서는 헤더를 포함하지 않은 순수한 payload 의 데이터 크기로 인식되기 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 설명하기 위한 개념이 &lt;b&gt;MTU(Maximum Transmission Unit) &lt;/b&gt;와 &lt;b&gt;MSS(&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;Maximum Segment Size) &lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;background-color: #ffffff; color: #333333; text-align: start;&quot;&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;MTU 와 PDU&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock floatLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;OSI 7계층과 PDU.png&quot; data-origin-width=&quot;546&quot; data-origin-height=&quot;848&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mLfxM/btsLRklul32/fAAj9ETY8SueNixgmh1nUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mLfxM/btsLRklul32/fAAj9ETY8SueNixgmh1nUK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mLfxM/btsLRklul32/fAAj9ETY8SueNixgmh1nUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmLfxM%2FbtsLRklul32%2FfAAj9ETY8SueNixgmh1nUK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;266&quot; height=&quot;413&quot; data-filename=&quot;OSI 7계층과 PDU.png&quot; data-origin-width=&quot;546&quot; data-origin-height=&quot;848&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;누군가는&lt;b&gt; MTU&lt;/b&gt;&amp;nbsp;를 네트워크 계층 트랜잭션 에서 통신할 수 있는 &lt;b&gt;가장 큰 프로토콜 데이터 단위 (PDU)&lt;/b&gt;의 크기라고 정의하기도 한다. (&lt;a href=&quot;https://en.wikipedia.org/wiki/Maximum_transmission_unit&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;나무위키 참조&lt;/a&gt;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 앞서 설명한 &lt;b&gt;MTU&lt;/b&gt; 의 정의인 &lt;b&gt;데이터 링크 계층(OSI 2계층)&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;에서 허용하는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;최대 페이로드 크기&lt;/b&gt;가 시초의 정의라고 필자는 생각하지만, 중요한건 증명이 아니라 PDU 가 무엇을 설명하고 싶어서 나온 용어인가이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;헤더나 부가정보를 제외한 &lt;b&gt;순수 데이터의 크기&lt;/b&gt;를 측정하고 공유하고 싶기에 해당 용어가 생겨났다고 본다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞서 OSI 7 Layer 의 2계층인&lt;b&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;Data Link Layer&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;에서는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;Ethernet 프로토콜&lt;/b&gt;을 사용한다고 설명하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, 3계층인 &lt;b&gt;Network Layer&lt;/b&gt;&amp;nbsp;에서는&amp;nbsp;&lt;b&gt;IP 프로토콜&lt;/b&gt;을 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;MTU 와 MSS&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2025-01-18 오후 5.56.02.png&quot; data-origin-width=&quot;1212&quot; data-origin-height=&quot;392&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cfrsTD/btsLRSPvrMF/APIynN4AcFedhRcMLd4XU0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cfrsTD/btsLRSPvrMF/APIynN4AcFedhRcMLd4XU0/img.png&quot; data-alt=&quot;Ethernet 프로토콜의 PDU 인 프레임의 구성&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cfrsTD/btsLRSPvrMF/APIynN4AcFedhRcMLd4XU0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcfrsTD%2FbtsLRSPvrMF%2FAPIynN4AcFedhRcMLd4XU0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;773&quot; height=&quot;250&quot; data-filename=&quot;스크린샷 2025-01-18 오후 5.56.02.png&quot; data-origin-width=&quot;1212&quot; data-origin-height=&quot;392&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Ethernet 프로토콜의 PDU 인 프레임의 구성&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 이미지는 &lt;b&gt;Ethernet&lt;/b&gt; 프로토콜의 PDU 인 &lt;b&gt;프레임의 구성&lt;/b&gt;을 보여주고 있으며 검색을 하면 흔하게 접할 수 있는 이미지이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;MTU&lt;/b&gt; 는 참조정보(헤더,FCS)가 아닌 &lt;b&gt;순수 데이터를 측정하기 위해 태어난 단위&lt;/b&gt;라고 앞서 설명하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 &lt;b&gt;Ethernet MTU&lt;/b&gt; 는 Ethernet 프로토콜의 참조정보를 제외한 크기를 나타내지만, &lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;&lt;b&gt;IP MTU&lt;/b&gt; 는 이상하게도 &lt;b&gt;IP 헤더를 포함&lt;/b&gt;한 크기로 측정한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;MTU&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;의 정의가&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;데이터 링크 계층(OSI 2계층)&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;에서 허용하는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;최대 페이로드 크기&lt;/b&gt;가 정의의 시초였다고 생각하는 이유가 바로 &lt;b&gt;IP MTU&lt;/b&gt; 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;MSS(&lt;span style=&quot;background-color: #ffffff; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;Maximum Segment Size)&lt;/span&gt;&lt;/b&gt;는 용어에서 보이듯 세그먼트를 사용하는 4계층의 PDU의 관한 용어이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;Maximum Segment Size &lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;라는 영문을&lt;/span&gt;&amp;nbsp;보면 알 수 있듯이 &lt;b&gt;MTU&lt;/b&gt; 와 같은 뜻을 담고 있지만 계층을 구분하고 싶어 생겨난 단어라는 것을 짐작할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, MSS 의 정의는 &lt;b&gt;Transport 계층(OSI 4계층)&lt;/b&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;에서 허용하는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;최대 페이로드 크기&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;때문에 Ethernet MTU 와 동일하게 &lt;b&gt;4계층까지의 부가정보&lt;/b&gt;(헤더 등)를&lt;b&gt; 제외&lt;/b&gt;한 데이터의 크기를 나타낸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 사용자가 사용하는 Application 에서는 MTU 가 1500 인 서버에 데이터를 보내고 싶다면, 헤더 값을 고려하여 1500 보다 작게 보내야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 &lt;span style=&quot;background-color: #ffffff; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;ping의 경우 IP 헤더(20바이트) + ICMP 헤더(8바이트)로 요청을 보내는 것이기 &lt;/span&gt;&lt;span style=&quot;background-color: #ffffff; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;때문에 MSS는 1472 까지 가능하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;데이터를 보낼 때 항상 실험을 해야된다면 너무 비효율적인 것 같은데..  &lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다. 내 주변 LAN 의 구성이야 사용자가 노력해서 알 수 있다고 하지만, 데이터를 보낼 서버의 LAN 은 사용자가 어떻게 매번 조사를 하겠는가. 애초에 도착지점까지의 모든 장치의 MTU 를 미리 알 수 있다하더라도, 유지보수 이후 MTU 가 변경된다면 무슨소용인가.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt; 이를 해결하기 위한 기술이 &lt;b&gt;PMTUD(Path MTU Discovery)&lt;/b&gt; 이며 경로 MTU를 동적으로 탐색하여 데이터를 분할하지 않고 최적 크기의 패킷으로 전송되도록 조정하는 역할을 수행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;PMTUD.png&quot; data-origin-width=&quot;1800&quot; data-origin-height=&quot;628&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dpwDa0/btsLQ7mrGXG/xId0MtlBpr4IWenwH5KAR1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dpwDa0/btsLQ7mrGXG/xId0MtlBpr4IWenwH5KAR1/img.png&quot; data-alt=&quot;PMTUD 간략 개요&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dpwDa0/btsLQ7mrGXG/xId0MtlBpr4IWenwH5KAR1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdpwDa0%2FbtsLQ7mrGXG%2FxId0MtlBpr4IWenwH5KAR1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1800&quot; height=&quot;628&quot; data-filename=&quot;PMTUD.png&quot; data-origin-width=&quot;1800&quot; data-origin-height=&quot;628&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;PMTUD 간략 개요&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 대충 봐도 알 수 있듯이 &lt;b&gt;초기 MTU 탐색 과정에 비용&lt;/b&gt;이 발생하고, 경로상에 있는 네트워크 장치들은 응답값에 ICMP 메시지를 작성하고 그 안에 MTU 를 넣어 반환하게 되는데 &lt;b&gt;보안상의 이유로 ICMP 메시지를 차단하는 네트워크&lt;/b&gt;가 있을 수도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이에 대해 자세히 설명하게 되면 포스팅이 길어지기에 여기에서 마친다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;패킷의 크기에 대하여&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오해가 있을까봐 첨언합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;패킷의 크기가 크면 당연히 slice 과정과 merge 과정의 오버헤드는 물론 헤더의 중복에 대한 오버헤드도 줄일 수 있다는 장점등이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반대로 작다면 손실된 패킷에 대한 재전송에 대한 부담이 적어진다는 점과 혼잡한 네트워크 속에서 대역폭을 나눠쓰기 때문에 네트워크 혼잡을 완화할 수 있다는 장점등이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 57px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 10.1163%; height: 19px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 42.907%; height: 19px;&quot;&gt;패킷이 커요!&lt;/td&gt;
&lt;td style=&quot;width: 46.9767%; height: 19px;&quot;&gt;패킷이 작아요!&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 10.1163%; height: 19px;&quot;&gt;장점&lt;/td&gt;
&lt;td style=&quot;width: 42.907%; height: 19px;&quot;&gt;&lt;span style=&quot;background-color: #f9f9f9; color: #333333; text-align: start;&quot;&gt;1.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #f9f9f9; color: #333333; text-align: start;&quot;&gt;헤더 오버헤드 감소&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #f9f9f9; color: #333333; text-align: start;&quot;&gt;2.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #f9f9f9; color: #333333; text-align: start;&quot;&gt;CPU 부하 감소&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #f9f9f9; color: #333333; text-align: start;&quot;&gt;3.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #f9f9f9; color: #333333; text-align: start;&quot;&gt;전송 속도 감소&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 46.9767%; height: 19px;&quot;&gt;1. 패킷 손실 시 재전송 부담 감소&lt;br /&gt;2. 네트워크 혼잡 완화&lt;br /&gt;3. 네트워크 경로상의 Fragmentation 방지&lt;br /&gt;4. 지연 시간 감소&lt;br /&gt;5. 오류 확산 방지&lt;br /&gt;6. 일부 프로토콜에서 헤더 압축 효율성 증가&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 10.1163%;&quot;&gt;적합한 환경&lt;/td&gt;
&lt;td style=&quot;width: 42.907%;&quot;&gt;&lt;b&gt;고속 데이터 전송&lt;/b&gt;과 &lt;b&gt;효율성&lt;/b&gt;이 중요한 곳&lt;br /&gt;&lt;br /&gt;ex) 데이터 센터 네트워크, 고속 전송 네트워크, 클라우드 및 파일 서비스, VPN/터널링 환경&lt;/td&gt;
&lt;td style=&quot;width: 46.9767%;&quot;&gt;&lt;b&gt;호환성 문제&lt;/b&gt;, &lt;b&gt;네트워크 안정성&lt;/b&gt; 및 &lt;b&gt;경로 MTU 탐색비용 감소&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;ex) 인터넷 연결이 불안정한 지역, 무선 네트워크, 실시간 애플리케이션, 혼잡한 네트워크, VPN/터널링 환경&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;MTU (&lt;span style=&quot;background-color: #ffffff; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;Maximum Transmission Unit)&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;정의:&lt;br /&gt;&lt;/b&gt;네트워크에서 &lt;b&gt;데이터 링크 계층(OSI 2계층)&lt;/b&gt;에서 허용하는 &lt;b&gt;최대 페이로드 크기&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;MSS (&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;Maximum Segment Size&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;background-color: #ffffff; font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;)&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;정의:&lt;br /&gt;&lt;/b&gt;네트워크에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;전송 계층(OSI 4계층)&lt;/b&gt;에서 허용하는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;최대 페이로드 크기&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Network Basis</category>
      <author>DevPing9_</author>
      <guid isPermaLink="true">https://developer-ping9.tistory.com/676</guid>
      <comments>https://developer-ping9.tistory.com/676#entry676comment</comments>
      <pubDate>Sat, 18 Jan 2025 20:23:37 +0900</pubDate>
    </item>
    <item>
      <title>[Network] 노드와 네트워크 장치, 링크와 회선</title>
      <link>https://developer-ping9.tistory.com/675</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. 노드 (Node)&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;정의:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터를 생성하거나 소비하는 장치&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;예시:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;클라이언트 노드:&lt;/b&gt; 컴퓨터, 스마트폰, IoT 기기 등&lt;/li&gt;
&lt;li&gt;&lt;b&gt;서버 노드:&lt;/b&gt; 웹 서버, 데이터베이스 서버&lt;/li&gt;
&lt;li&gt;&lt;b&gt;기타 노드:&lt;/b&gt; 네트워크 프린터, NAS(Network Attached Storage), IoT 센서&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;특징:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;일반적으로 데이터의 생성 또는 최종 소비를 담당&lt;/li&gt;
&lt;li&gt;사용자가 직접 상호작용하는 장치가 많음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. 네트워크 장비 (Network Device)&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;정의:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;노드 간의 데이터 흐름을 관리하고 최적화하는 데 사용되는 장치&lt;/li&gt;
&lt;li&gt;자체적으로 데이터를 생성하거나 소비하지는 않지만, 데이터를 전달하거나 처리하는 데 중요한 역할을 수행&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;예시:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;스위치(Switch):&lt;/b&gt; LAN(Local Area Network)에서 데이터를 전달&lt;/li&gt;
&lt;li&gt;&lt;b&gt;라우터(Router):&lt;/b&gt; 서로 다른 네트워크 간 데이터 전송을 관리&lt;/li&gt;
&lt;li&gt;&lt;b&gt;허브(Hub):&lt;/b&gt; 데이터를 단순히 모든 연결된 장치로 브로드캐스트&lt;/li&gt;
&lt;li&gt;&lt;b&gt;방화벽(Firewall):&lt;/b&gt; 네트워크 보안을 관리&lt;/li&gt;
&lt;li&gt;&lt;b&gt;액세스 포인트(AP):&lt;/b&gt; 무선 네트워크에 장치를 연결&lt;/li&gt;
&lt;li&gt;&lt;b&gt;LAN 카드&lt;/b&gt; : 노드 내부에 설치되어 노드를 네트워크에 연결&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;특징:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;네트워크의 물리적 및 논리적 연결을 관리&lt;/li&gt;
&lt;li&gt;트래픽 최적화, 보안, 네트워크 제어와 같은 기능 제공&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. 링크(Link)&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;정의:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터가 이동할 수 있는 물리적 또는 논리적 연결 통로&lt;/li&gt;
&lt;li&gt;노드와 네트워크 장치를 물리적/논리적으로 연결&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;예시:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이더넷 케이블, 광케이블, Wi-Fi 신호, 블루투스 연결, 위성 통신 링크, VPN&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4. 회선(Circut)&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;정의:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;링크 위에 설정되는 특정 사용자나 목적을 위한 &lt;b&gt;전용&amp;nbsp;통신 경로&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;예시:&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;두 지점을 연결하는 광케이블 링크 위에 전용 회선을 설정&lt;/li&gt;
&lt;li&gt;ATM 네트워크의 가상 회선, 전화 회선, 전용 임대 회선&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;* ATM 네트워크&lt;/b&gt; : 데이터를 고정된 크기의 셀(Cell)로 분할하여 전송하는 네트워크 통신 기술&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;# 요약 비교&lt;/b&gt;&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 95px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style12&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 8.5465%; height: 19px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 19.7093%; height: 19px;&quot;&gt;노드(Node)&lt;/td&gt;
&lt;td style=&quot;width: 26.0466%; height: 19px;&quot;&gt;네트워크 장치(Network Device)&lt;/td&gt;
&lt;td style=&quot;width: 20.6976%; height: 19px;&quot;&gt;링크(Link)&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 19px;&quot;&gt;회선(Circut)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 38px;&quot;&gt;
&lt;td style=&quot;width: 8.5465%; height: 38px;&quot;&gt;역할&lt;/td&gt;
&lt;td style=&quot;width: 19.7093%; height: 38px;&quot;&gt;&lt;span&gt;데이터의 생성, 소비, 처리&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 26.0466%; height: 38px;&quot;&gt;데이터의 전달 및 네트워크 최적화&lt;/td&gt;
&lt;td style=&quot;width: 20.6976%; height: 38px;&quot;&gt;데이터의 이동 통로&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 38px;&quot;&gt;&lt;span&gt;링크 위에 설정되는&lt;span&gt;&amp;nbsp;&lt;/span&gt;특정 사용자나 목적을 위한&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;전용&amp;nbsp;통신 경로&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;width: 8.5465%; height: 19px;&quot;&gt;예시&lt;/td&gt;
&lt;td style=&quot;width: 19.7093%; height: 19px;&quot;&gt;PC, 스마트폰, 서버, IoT 장치&lt;/td&gt;
&lt;td style=&quot;width: 26.0466%; height: 19px;&quot;&gt;스위치, 라우터, 방화벽, 허브&lt;/td&gt;
&lt;td style=&quot;width: 20.6976%; height: 19px;&quot;&gt;&lt;span&gt;이더넷 케이블, 광케이블, Wi-Fi 신호, 블루투스 연결, 위성 통신 링크, VPN&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 19px;&quot;&gt;&lt;span&gt;ATM 네트워크 가상 회선, 전화 회선, 전용 임대 회선&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Network Basis</category>
      <author>DevPing9_</author>
      <guid isPermaLink="true">https://developer-ping9.tistory.com/675</guid>
      <comments>https://developer-ping9.tistory.com/675#entry675comment</comments>
      <pubDate>Fri, 17 Jan 2025 17:53:08 +0900</pubDate>
    </item>
    <item>
      <title>[Spring] 트랜잭션에 대한 실험과 고찰 (Self-invocation, 프록시가 메서드를 실행하기까지의 과정)</title>
      <link>https://developer-ping9.tistory.com/669</link>
      <description>&lt;figure id=&quot;og_1733048763753&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[Spring] 예외 발생시 Spring DB 트랜잭션 롤백 안되는 경우&quot; data-og-description=&quot;배경지식Checked Exception 은 개발자가 인지한 예외라 약속한다.Unchecked Exception 은 개발자가 인지하지 못한 예외라 약속한다.try-catch 문에서 catch 된 Exception 은 개발자가 인지한 예외라 약속한다.스프&quot; data-og-host=&quot;developer-ping9.tistory.com&quot; data-og-source-url=&quot;https://developer-ping9.tistory.com/667&quot; data-og-url=&quot;https://developer-ping9.tistory.com/667&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/TLl4S/hyXGIfy3v4/APrjd0TbUTWsacuBSvJcyk/img.jpg?width=271&amp;amp;height=186&amp;amp;face=0_0_271_186,https://scrap.kakaocdn.net/dn/L9geO/hyXGAhwuGu/y5yPMFLriQ4HdyuyFgXtL1/img.jpg?width=271&amp;amp;height=186&amp;amp;face=0_0_271_186&quot;&gt;&lt;a href=&quot;https://developer-ping9.tistory.com/667&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer-ping9.tistory.com/667&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/TLl4S/hyXGIfy3v4/APrjd0TbUTWsacuBSvJcyk/img.jpg?width=271&amp;amp;height=186&amp;amp;face=0_0_271_186,https://scrap.kakaocdn.net/dn/L9geO/hyXGAhwuGu/y5yPMFLriQ4HdyuyFgXtL1/img.jpg?width=271&amp;amp;height=186&amp;amp;face=0_0_271_186');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[Spring] 예외 발생시 Spring DB 트랜잭션 롤백 안되는 경우&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;배경지식Checked Exception 은 개발자가 인지한 예외라 약속한다.Unchecked Exception 은 개발자가 인지하지 못한 예외라 약속한다.try-catch 문에서 catch 된 Exception 은 개발자가 인지한 예외라 약속한다.스프&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer-ping9.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Spring DB 트랜잭션의 롤백 유무에 대해 정리하다가 프록시 객체가 언제 생성되는지, 어떤 원리로 만들어지는지 고찰을 하기 위해 여러 실험을 진행해보았다. 다른 블로그 글을 읽어도 이해가 잘안되고, 블로그마다 말이 좀 다른게 있어 쉽게 믿을 수가 없었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;무엇보다 제일 궁금했던 점은 &lt;b&gt;프록시가 나의 서비스클래스를 상속받아서 만들어지는지, 아니면 주입받아서 사용하는지&lt;/b&gt;의 여부였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;경제적인 관점에서 주입받아서 사용하는 편이 비용적으로 저렴하니까 당연하다 생각하였는데, 다른 블로그 포스팅에서 상속받아서 만들어낸다는 글도 있어서 무시할 수가 없었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;검증 전 필자가 생각한 이상적인 프록시 객체의 코드&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1733054145216&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Class
class ProxyService(
	private val myUserService: MyUserService,
): Proxy {
	fun registerUser(...) {
    	Proxy.preProcess()
        myUserService.registerUser(...)
        Proxy.postProcess()
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요롷게 안되어있으면 컨트리뷰트 해봐야지!!! +_+&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 내용들은 스프링 라이브러리 코드를 기반으로 디버깅하여 모두 확인 검증하였으니 안전하게(?) 받아들여도 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;검증 방법 따라해보기&lt;/b&gt;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. CglibAopProxy (&lt;span style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot;&gt;프록시 생성 과정 및 원객체 메서드 실행 디버깅 가능)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. TransactionInterceptor (&lt;span style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot;&gt;트랜잭션 인터셉터 실행과정 디버깅 가능)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. logging.level.org.springframework.transaction.interceptor: TRACE &lt;br /&gt;&amp;nbsp; &amp;nbsp;(트랜잭션 열리고 닫히는 과정을 로깅을 통해 관찰가능)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. &lt;span style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot;&gt;TransactionInterceptor.invoke() -&amp;gt; &lt;span style=&quot;background-color: #fafafa; color: #333333; text-align: start;&quot;&gt;CglibAopProxy.proceed() 의 this.target 의 주소값과 서비스 메서드가 실행될때의 서비스 주소값을 비교&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;@Transactional 어노테이션으로 인해 생성된 프록시가 메서드를 실행하기 까지의 과정&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1733051261239&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// &amp;lt;When Application Initialized&amp;gt;
1. Parsing the Annotation
2. Proxy Creation

// &amp;lt;When Proxy(service) method called&amp;gt;
3. Transaction Advice Execution
4. Method Execution (해당 메서드는 프록시 객체가 아닌 서비스 객체의 메서드이다.)
5. Transaction Commit&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 주목할 점은 &lt;b&gt;4. Method Excution &lt;/b&gt;이 프록시 객체가 아닌&lt;b&gt; 스프링빈의 메서드&lt;/b&gt;라는 점이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 프록시는 우리가 작성한 서비스를 상속하여 생성되는 것이 아니라 주입 받아서 생성되는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 점을 검증하기 위해서 정말 고생을 많이했다...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;스프링빈의 메서드라는 점 하나로 많은게 당연시 된다.&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1733055686545&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;1. private 메서드에는 @Transactional 을 붙여도 동작하지 않는다.
2. Self-invocation 시, 하위 메서드들에 붙은 @Transcational 은 무시된다.
3. Self-invocation 시, 하위 메서드들은 상위 메서드의 트랜잭션에 종속된다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 상위 메서드의 트랜잭션과 하위 메서드의 &lt;b&gt;트랜잭션을 분리하여 처리&lt;/b&gt;하고 싶다면, 하위 메서드가 프록시객체에서 호출되어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 실현하기 위해 아래의 방법을 사용할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1733055705586&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;1. 하위 메서드와 상위 메서드의 클래스를 분리시킨다.
2. 순환참조로 자기자신을 주입받은 후, 순환참조된 객체에서 하위메서드를 호출한다. (권장하지 않습니다)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2번은 권장하지 않는데, &lt;b&gt;단일책임의 원칙&lt;/b&gt;으로 설계된 클래스의 트랜잭션이 서로 분리되어 처리되어야 할 일은 거의 없을 것이기 때문이다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 2번의 경우가 발생한다면 &lt;b&gt;클래스의 책임분리가 잘되어있는지 고민해야하는 시점&lt;/b&gt;이라고 생각한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;+ 트랜잭션 롤백유무에 관한 실험과 결과&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Self-invocation&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;color: #333333; text-align: left; border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style15&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;상위 메서드&lt;br /&gt;@Transactional&lt;/td&gt;
&lt;td&gt;상위 메서드 예외&lt;/td&gt;
&lt;td&gt;하위 메서드&lt;br /&gt;@Transactional&lt;/td&gt;
&lt;td&gt;하위 메서드 예외&lt;/td&gt;
&lt;td&gt;롤백유무 (상위 / 하위)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;O&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;O&lt;/td&gt;
&lt;td&gt;O(Runtime)&lt;/td&gt;
&lt;td&gt;O / O&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;O&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;O(rollbackFor)&lt;/td&gt;
&lt;td&gt;O(Checked)&lt;/td&gt;
&lt;td&gt;X / X&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;O(rollbackFor)&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;O or X&lt;/td&gt;
&lt;td&gt;O(Checked)&lt;/td&gt;
&lt;td&gt;O / O&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;O&lt;/td&gt;
&lt;td&gt;O(Runtime)&lt;/td&gt;
&lt;td&gt;O(requires_new)&lt;/td&gt;
&lt;td&gt;X&lt;/td&gt;
&lt;td&gt;O / O&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p style=&quot;color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Non-self-invocation&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;color: #333333; text-align: start; border-collapse: collapse; width: 100%; height: 156px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style15&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 36px;&quot;&gt;
&lt;td style=&quot;height: 36px;&quot;&gt;상위 메서드&lt;br /&gt;@Transactional&lt;/td&gt;
&lt;td style=&quot;height: 36px;&quot;&gt;상위 메서드 예외&lt;/td&gt;
&lt;td style=&quot;height: 36px;&quot;&gt;하위 메서드&lt;br /&gt;@Transactional&lt;/td&gt;
&lt;td style=&quot;height: 36px;&quot;&gt;하위 메서드 예외&lt;/td&gt;
&lt;td style=&quot;height: 36px;&quot;&gt;롤백유무 (상위 / 하위)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;X&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;O(Runtime)&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;O / O&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;X&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;O(rollbackFor)&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;O(Checked)&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;O / O&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;O(rollbackFor)&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;X&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;O or &lt;b&gt;X&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;O(Checked)&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;&lt;b&gt;O / O&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;O&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;O(Runtime)&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;O(requires_new)&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;X&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;O / X&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;&lt;b&gt;O&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;&lt;b&gt;O(requires_new)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;&lt;b&gt;O(Runtime)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;&lt;b&gt;O / O&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 35px;&quot;&gt;
&lt;td style=&quot;height: 35px;&quot;&gt;&lt;b&gt;O&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 35px;&quot;&gt;&lt;b&gt;X&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 35px;&quot;&gt;&lt;b&gt;O(requires_new,&lt;/b&gt;&lt;br /&gt;&lt;b&gt;rollbackFor)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 35px;&quot;&gt;&lt;b&gt;O(Checked)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 35px;&quot;&gt;&lt;b&gt;X / O&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;+ 컨트리뷰트 할 거리 없나 싶어 추가로 실험/검증한 사실&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1733056438850&quot; class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;1. @Transactional 어노테이션을 가지지 않은 서비스빈들은 프록시 객체로 생성되지 않고 스프링빈으로 생성 됨.
2. @Transactional 어노테이션이 없더라도, 순환참조로 자기자신을 참조할 경우 프록시 객체가 생성 됨.
3. 트랜잭션이 분리가 되더라도 Runtime Exception 이 상위 메서드에 전파가 되고 상위 메서드에서 따로 핸들링하지 않는다면 상위 메서드의 트랜잭션도 롤백된다.&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;스프링에 컨트리뷰트 해보고 싶었는데 역시 이미 잘 만들어져있다 ㅎㅎㅎ... 쳇...&lt;/p&gt;</description>
      <category>Back End/Spring Framework</category>
      <author>DevPing9_</author>
      <guid isPermaLink="true">https://developer-ping9.tistory.com/669</guid>
      <comments>https://developer-ping9.tistory.com/669#entry669comment</comments>
      <pubDate>Sun, 1 Dec 2024 21:36:27 +0900</pubDate>
    </item>
    <item>
      <title>[Spring] 예외 발생시 Spring DB 트랜잭션 롤백 안되는 경우</title>
      <link>https://developer-ping9.tistory.com/667</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;배경지식&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Checked Exception 은 개발자가 인지한 예외라 약속한다.&lt;/li&gt;
&lt;li&gt;Unchecked Exception 은 개발자가 인지하지 못한 예외라 약속한다.&lt;/li&gt;
&lt;li&gt;try-catch 문에서 catch 된 Exception 은 개발자가 인지한 예외라 약속한다.&lt;/li&gt;
&lt;li&gt;스프링은 개발자가 인지한 예외에 대해서는 기본적으로 롤백을 진행하지 않는다.&lt;/li&gt;
&lt;li&gt;예외가 발생한 메서드의 Propagation 레벨이 Required(default) 가 아니면 부모트랜잭션은 롤백되지 않는다.&lt;/li&gt;
&lt;li&gt;프록시가 Self invocation 을 시도할 경우 경우에 따라 트랜잭션이 롤백되지 않을 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1733119032662&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[Spring] 트랜잭션에 대한 실험과 고찰 (Self-invocation, 프록시가 메서드를 실행하기까지의 과정)&quot; data-og-description=&quot;[Spring] 예외 발생시 Spring DB 트랜잭션 롤백 안되는 경우배경지식Checked Exception 은 개발자가 인지한 예외라 약속한다.Unchecked Exception 은 개발자가 인지하지 못한 예외라 약속한다.try-catch 문에서 catc&quot; data-og-host=&quot;developer-ping9.tistory.com&quot; data-og-source-url=&quot;https://developer-ping9.tistory.com/669&quot; data-og-url=&quot;https://developer-ping9.tistory.com/669&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/SGn8O/hyXGHVvzJW/g7ujh27wkjusMYt30SSmuk/img.jpg?width=225&amp;amp;height=224&amp;amp;face=0_0_225_224,https://scrap.kakaocdn.net/dn/oHYp2/hyXGKLq9gc/EZBkz6xkD4MbV4uVqkFWP0/img.jpg?width=225&amp;amp;height=224&amp;amp;face=0_0_225_224&quot;&gt;&lt;a href=&quot;https://developer-ping9.tistory.com/669&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://developer-ping9.tistory.com/669&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/SGn8O/hyXGHVvzJW/g7ujh27wkjusMYt30SSmuk/img.jpg?width=225&amp;amp;height=224&amp;amp;face=0_0_225_224,https://scrap.kakaocdn.net/dn/oHYp2/hyXGKLq9gc/EZBkz6xkD4MbV4uVqkFWP0/img.jpg?width=225&amp;amp;height=224&amp;amp;face=0_0_225_224');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[Spring] 트랜잭션에 대한 실험과 고찰 (Self-invocation, 프록시가 메서드를 실행하기까지의 과정)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;[Spring] 예외 발생시 Spring DB 트랜잭션 롤백 안되는 경우배경지식Checked Exception 은 개발자가 인지한 예외라 약속한다.Unchecked Exception 은 개발자가 인지하지 못한 예외라 약속한다.try-catch 문에서 catc&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;developer-ping9.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;발생 케이스&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;발생한 예외가 Checked Exception&amp;nbsp;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;@Transational 어노테이션에 rollbackFor 을 설정하지 않은 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;발생한 예외가 Unchecked Exception
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;try-catch 구문안에서 핸들링되는 경우 &lt;span style=&quot;color: #ef5369;&quot;&gt;(&lt;span style=&quot;text-align: start;&quot;&gt;Unchecked Exception 을 왜 잡으려고 하는거에요?)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;@Transational 어노테이션에 noRollbackFor 가 설정된 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;자식 메서드의 Propagation 레벨이 Required 가 아닐 경우&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;프록시의 Self invocation 으로 인한 경우&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Reference&lt;/b&gt;&lt;/h4&gt;
&lt;figure id=&quot;og_1732778079914&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Rolling Back a Declarative Transaction :: Spring Framework&quot; data-og-description=&quot;You must carefully consider how specific a pattern is and whether to include package information (which isn&amp;rsquo;t mandatory). For example, &amp;quot;Exception&amp;quot; will match nearly anything and will probably hide other rules. &amp;quot;java.lang.Exception&amp;quot; would be correct if &amp;quot;E&quot; data-og-host=&quot;docs.spring.io&quot; data-og-source-url=&quot;https://docs.spring.io/spring-framework/reference/data-access/transaction/declarative/rolling-back.html&quot; data-og-url=&quot;https://docs.spring.io/spring-framework/reference/data-access/transaction/declarative/rolling-back.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.spring.io/spring-framework/reference/data-access/transaction/declarative/rolling-back.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.spring.io/spring-framework/reference/data-access/transaction/declarative/rolling-back.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Rolling Back a Declarative Transaction :: Spring Framework&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;You must carefully consider how specific a pattern is and whether to include package information (which isn&amp;rsquo;t mandatory). For example, &quot;Exception&quot; will match nearly anything and will probably hide other rules. &quot;java.lang.Exception&quot; would be correct if &quot;E&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.spring.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;figure id=&quot;og_1732700577154&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;응? 이게 왜 롤백되는거지? | 우아한형제들 기술블로그&quot; data-og-description=&quot;이 글은 얼마 전 에러로그 하나에 대한 호기심과 의문으로 시작해서 스프링의 트랜잭션 내에서 예외가 어떻게 처리되는지를 이해하기 위해 삽질을 해본 경험을 토대로 쓰여졌습니다. 스프링의 &quot; data-og-host=&quot;techblog.woowahan.com&quot; data-og-source-url=&quot;https://techblog.woowahan.com/2606/&quot; data-og-url=&quot;https://techblog.woowahan.com/2606/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/uysPx/hyXDaRKpEt/pHoykepik2hEB7rvwwmtg0/img.jpg?width=1640&amp;amp;height=856&amp;amp;face=0_0_1640_856,https://scrap.kakaocdn.net/dn/cXvPiG/hyXGOfa3le/K65w8Yq1FWRSz9QzTp9KM0/img.jpg?width=1640&amp;amp;height=856&amp;amp;face=0_0_1640_856,https://scrap.kakaocdn.net/dn/2wKR6/hyXDhQRHaT/nkYTKCt1mUSSFoiCaiBbE0/img.png?width=1200&amp;amp;height=290&amp;amp;face=0_0_1200_290&quot;&gt;&lt;a href=&quot;https://techblog.woowahan.com/2606/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://techblog.woowahan.com/2606/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/uysPx/hyXDaRKpEt/pHoykepik2hEB7rvwwmtg0/img.jpg?width=1640&amp;amp;height=856&amp;amp;face=0_0_1640_856,https://scrap.kakaocdn.net/dn/cXvPiG/hyXGOfa3le/K65w8Yq1FWRSz9QzTp9KM0/img.jpg?width=1640&amp;amp;height=856&amp;amp;face=0_0_1640_856,https://scrap.kakaocdn.net/dn/2wKR6/hyXDhQRHaT/nkYTKCt1mUSSFoiCaiBbE0/img.png?width=1200&amp;amp;height=290&amp;amp;face=0_0_1200_290');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;응? 이게 왜 롤백되는거지? | 우아한형제들 기술블로그&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;이 글은 얼마 전 에러로그 하나에 대한 호기심과 의문으로 시작해서 스프링의 트랜잭션 내에서 예외가 어떻게 처리되는지를 이해하기 위해 삽질을 해본 경험을 토대로 쓰여졌습니다. 스프링의&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;techblog.woowahan.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;figure id=&quot;og_1732777537252&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[이슈 #1] Spring Transaction의 Self Invocation 이슈&quot; data-og-description=&quot;Spring Transaction의 Self Invocation 이슈 문제 인식 Spring Security를 이용한 OAuth 로그인 기능을 구현하기 위해 커스텀한 OAuth2UserService를 개발하던 중, 영속 상태에 있는 인스턴스의 필드 변경 사항이 DB에 &quot; data-og-host=&quot;yejun-the-developer.tistory.com&quot; data-og-source-url=&quot;https://yejun-the-developer.tistory.com/13&quot; data-og-url=&quot;https://yejun-the-developer.tistory.com/13&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/c3BoQ4/hyXDibjljW/f1LTHdz8JCGRYzEbY0lETK/img.png?width=800&amp;amp;height=390&amp;amp;face=0_0_800_390,https://scrap.kakaocdn.net/dn/iVz1j/hyXGBtv4fb/oZ1qeIsfDsD7AG0CKLlaBk/img.png?width=800&amp;amp;height=390&amp;amp;face=0_0_800_390,https://scrap.kakaocdn.net/dn/eAwNX/hyXGIe6D0h/erXIrDgxd5q0pK9p3fBNUk/img.png?width=1086&amp;amp;height=590&amp;amp;face=0_0_1086_590&quot;&gt;&lt;a href=&quot;https://yejun-the-developer.tistory.com/13&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://yejun-the-developer.tistory.com/13&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/c3BoQ4/hyXDibjljW/f1LTHdz8JCGRYzEbY0lETK/img.png?width=800&amp;amp;height=390&amp;amp;face=0_0_800_390,https://scrap.kakaocdn.net/dn/iVz1j/hyXGBtv4fb/oZ1qeIsfDsD7AG0CKLlaBk/img.png?width=800&amp;amp;height=390&amp;amp;face=0_0_800_390,https://scrap.kakaocdn.net/dn/eAwNX/hyXGIe6D0h/erXIrDgxd5q0pK9p3fBNUk/img.png?width=1086&amp;amp;height=590&amp;amp;face=0_0_1086_590');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[이슈 #1] Spring Transaction의 Self Invocation 이슈&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Spring Transaction의 Self Invocation 이슈 문제 인식 Spring Security를 이용한 OAuth 로그인 기능을 구현하기 위해 커스텀한 OAuth2UserService를 개발하던 중, 영속 상태에 있는 인스턴스의 필드 변경 사항이 DB에&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;yejun-the-developer.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Back End/Spring Framework</category>
      <author>DevPing9_</author>
      <guid isPermaLink="true">https://developer-ping9.tistory.com/667</guid>
      <comments>https://developer-ping9.tistory.com/667#entry667comment</comments>
      <pubDate>Wed, 27 Nov 2024 18:44:15 +0900</pubDate>
    </item>
    <item>
      <title>[트러블슈팅] You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near (~~~)</title>
      <link>https://developer-ping9.tistory.com/666</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-11-27 오후 6.07.41.png&quot; data-origin-width=&quot;2614&quot; data-origin-height=&quot;832&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bjzpcb/btsKYgcXJBf/JC6GbIlNcZtQTpe9hzEBvk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bjzpcb/btsKYgcXJBf/JC6GbIlNcZtQTpe9hzEBvk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bjzpcb/btsKYgcXJBf/JC6GbIlNcZtQTpe9hzEBvk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbjzpcb%2FbtsKYgcXJBf%2FJC6GbIlNcZtQTpe9hzEBvk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2614&quot; height=&quot;832&quot; data-filename=&quot;스크린샷 2024-11-27 오후 6.07.41.png&quot; data-origin-width=&quot;2614&quot; data-origin-height=&quot;832&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원인&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;DB 예약어를 컬럼명으로 사용하여 JPA가 SQL 문을 제대로 작성하지 못함&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해결&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;컬렴명 이스케이프&lt;/li&gt;
&lt;/ul&gt;
&lt;div style=&quot;background-color: #1e1f22; color: #bcbec4;&quot;&gt;
&lt;pre class=&quot;kotlin&quot; data-ke-language=&quot;kotlin&quot;&gt;&lt;code&gt;@Column(name=&quot;\&quot;left\&quot;&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;</description>
      <category>Back End/트러블슈팅</category>
      <author>DevPing9_</author>
      <guid isPermaLink="true">https://developer-ping9.tistory.com/666</guid>
      <comments>https://developer-ping9.tistory.com/666#entry666comment</comments>
      <pubDate>Wed, 27 Nov 2024 18:14:40 +0900</pubDate>
    </item>
    <item>
      <title>[MySQL] DB에 이상한 데이터가 있어요! (MySQL Strict mode)</title>
      <link>https://developer-ping9.tistory.com/602</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;발단&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 중에 누가봐도 이상한게 있었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테스트 데이터겠지, 그 때 어플리케이션 코드가 이상했겠지로는 설명이 안되는 최신데이터로 말이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;MySQL Strict Mode&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screen Shot 2023-10-02 at 5.46.57 PM.png&quot; data-origin-width=&quot;2328&quot; data-origin-height=&quot;298&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qVC6I/btswPYPMBYr/TQlAONeaPmxyx14tTanZcK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qVC6I/btswPYPMBYr/TQlAONeaPmxyx14tTanZcK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qVC6I/btswPYPMBYr/TQlAONeaPmxyx14tTanZcK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqVC6I%2FbtswPYPMBYr%2FTQlAONeaPmxyx14tTanZcK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2328&quot; height=&quot;298&quot; data-filename=&quot;Screen Shot 2023-10-02 at 5.46.57 PM.png&quot; data-origin-width=&quot;2328&quot; data-origin-height=&quot;298&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;MySQL 5.7 이상 버전들은 Strict Mode 가 기본설정이지만, 그 이하 버전들은 Strict Mode 가 꺼져있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Strict Mode 가 꺼져있다면 에러가 나야 할 쿼리들이 에러 없이 실행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;varchar(4) 로 설정했지만 10글자의 String 을 INSERT 문으로 작성하여도 성공적으로 실행된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래 포스팅에 잘 설명되어 있으니 참고하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1689931942910&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;MySQL Strict mode 끄기/켜기&quot; data-og-description=&quot;MySQL 5.7 부터는 STRICT_MODE 가 기본 설정이라고 하니 별도의 설정 작업이 필요없다.&quot; data-og-host=&quot;www.lesstif.com&quot; data-og-source-url=&quot;https://www.lesstif.com/dbms/mysql-strict-mode-24445406.html&quot; data-og-url=&quot;https://www.lesstif.com/dbms/mysql-strict-mode-24445406.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.lesstif.com/dbms/mysql-strict-mode-24445406.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.lesstif.com/dbms/mysql-strict-mode-24445406.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;MySQL Strict mode 끄기/켜기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;MySQL 5.7 부터는 STRICT_MODE 가 기본 설정이라고 하니 별도의 설정 작업이 필요없다.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.lesstif.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;그럼 Strict Mode 를 키면 되나?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미 Strict Mode 가 꺼진채로 운영중인 시스템에서 켜 버린다면 재앙이 발생할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;누군가는 Strict Mode 가 꺼진 것을 인지하고 어플리케이션 코드를 짜버렸을 수도 있으니까 말이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이럴 때에 변경 비용이 적은게 바로 마이크로서비스 아키텍처이구나... 라고 열심히 느끼고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;어플리케이션에서 값 검증&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 상황에서는 DB 를 믿지 못하니 insert 할 객체에 validation 을 모조리 걸어버리는 방법밖에는 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DB 가 할 일을 어플리케이션에서 중복으로 하는 느낌이 들어 매우 거부감이 들었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Strict Mode 가 켜져있다면, 어플리케이션에서는 값에 대한 검증을 미뤄도 될까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동료들과 토의 결과, 답은 '아니다' 로 귀결 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어플리케이션에서 값에 대한 검증을 하지 않는다면, Client 는 SQL Error Message 를 보게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;비지니스에 대한 에러메세지가 아닌 그저 특정 값을 insert/update 할 수 없다라는 메세지만 받기 때문에 작업자는 비지니스에 대한 요구사항을 정확히 알 수 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오래된 작업일수록 히스토리를 알기 어려워지는데, 그 때 에러메세지라도 비지니스적으로 작성이 되어있다면 &lt;b&gt;히스토리 파악에 도움이 되기에 유지보수비용을 줄일 수 있다&lt;/b&gt; 라는 것이 결론이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DBMS/MySQL</category>
      <author>DevPing9_</author>
      <guid isPermaLink="true">https://developer-ping9.tistory.com/602</guid>
      <comments>https://developer-ping9.tistory.com/602#entry602comment</comments>
      <pubDate>Mon, 2 Oct 2023 18:02:04 +0900</pubDate>
    </item>
  </channel>
</rss>