<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>개발자 시니</title>
    <link>https://dev-cini.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Tue, 14 Jul 2026 20:10:12 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>리신</managingEditor>
    <image>
      <title>개발자 시니</title>
      <url>https://tistory1.daumcdn.net/tistory/4981733/attach/355e0d7cbdd04070a338972186ee787f</url>
      <link>https://dev-cini.tistory.com</link>
    </image>
    <item>
      <title>TLS가 안 맞아서 통신이 안 됐다 &amp;ndash; 결국 JDK 올렸습니다</title>
      <link>https://dev-cini.tistory.com/95</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; ☁️ 새로 연동하는 협력사와 통신이 안 됐다&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;279&quot; data-start=&quot;211&quot; data-ke-size=&quot;size16&quot;&gt;우리 회사는 커머스 플랫폼이라&lt;br /&gt;협력사와의 API 연동 작업이 일상이다.&lt;/p&gt;
&lt;p data-end=&quot;279&quot; data-start=&quot;211&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;이건 내가 직접 처리한 건 아니고&lt;br /&gt;&lt;b&gt;우리팀에서 실제로 겪었던 실무 이슈다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;279&quot; data-start=&quot;211&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;325&quot; data-start=&quot;281&quot; data-ke-size=&quot;size16&quot;&gt;그날도 새로 들어온 협력사와&lt;br /&gt;&lt;b&gt;이미지 API 연동 작업&lt;/b&gt;을 진행하고 있었는데&amp;hellip;&lt;/p&gt;
&lt;blockquote data-end=&quot;363&quot; data-start=&quot;344&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;363&quot; data-start=&quot;346&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;이미지 API 요청 자체가 실패합니다.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&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-end=&quot;413&quot; data-start=&quot;361&quot; data-ke-size=&quot;size16&quot;&gt;다른 협력사들은 아무 문제 없이 잘 되는데&lt;br /&gt;&lt;b&gt;유독 이 새 협력사만 통신이 안 됐다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;413&quot; data-start=&quot;361&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;460&quot; data-start=&quot;415&quot; data-ke-size=&quot;size16&quot;&gt;우리는 당연히 로그부터 확인했고&lt;br /&gt;파고 또 파고&amp;hellip; 그러다 딱 하나가 의심됐다.&lt;/p&gt;
&lt;blockquote data-end=&quot;487&quot; data-start=&quot;462&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;487&quot; data-start=&quot;464&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;이거 TLS 버전 문제 아니야?&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&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;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;   우리는 JDK 1.7 , TLS는 1.0/1.1만 지원 &lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;630&quot; data-start=&quot;532&quot; data-ke-size=&quot;size16&quot;&gt;우리 시스템은 아주 건강한(?) 레거시다.&lt;br /&gt;현재까지도 &lt;b&gt;Java 1.7&lt;/b&gt;을 쓰고 있었고&lt;br /&gt;그 말은 곧 &lt;b&gt;지원 가능한 TLS 버전은 1.0 또는 1.1&lt;/b&gt;이라는 뜻.&lt;/p&gt;
&lt;p data-end=&quot;630&quot; data-start=&quot;532&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;749&quot; data-start=&quot;683&quot; data-ke-size=&quot;size16&quot;&gt;그런데 해당 협력사는&lt;br /&gt;&lt;b&gt;AWS 이미지 서버&lt;/b&gt;를 사용 중이었다.&lt;/p&gt;
&lt;p data-end=&quot;749&quot; data-start=&quot;683&quot; 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;style6&quot; /&gt;
&lt;h3 data-end=&quot;749&quot; data-start=&quot;683&quot; data-ke-size=&quot;size23&quot;&gt;  협력사에서 온 답변은 단 하나였다&lt;/h3&gt;
&lt;blockquote data-end=&quot;773&quot; data-start=&quot;726&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;773&quot; data-start=&quot;728&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;저희는 AWS를 사용하고 있어서&lt;br /&gt;하위 TLS 버전은 지원이 어렵습니다.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;799&quot; data-start=&quot;775&quot; data-ke-size=&quot;size16&quot;&gt;끝.&lt;br /&gt;딱히 기술적 이유나 대안은 없었다.&lt;/p&gt;
&lt;p data-end=&quot;799&quot; data-start=&quot;775&quot; 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;style6&quot; /&gt;
&lt;h3 data-end=&quot;799&quot; data-start=&quot;775&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;   그래서 AWS 엔지니어 친구한테 물어봤다 &lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;874&quot; data-start=&quot;836&quot; data-ke-size=&quot;size16&quot;&gt;내가 너무 답답해서&lt;br /&gt;친한 AWS 엔지니어 친구에게 직접 물어봤다.&lt;/p&gt;
&lt;blockquote data-end=&quot;905&quot; data-start=&quot;876&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;905&quot; data-start=&quot;878&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;야, 진짜 AWS는 TLS 1.1도 안 되냐?&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;915&quot; data-start=&quot;907&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;915&quot; data-start=&quot;907&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;915&quot; data-start=&quot;907&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;그 친구의 말:&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-end=&quot;995&quot; data-start=&quot;917&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;995&quot; data-start=&quot;919&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;&lt;b&gt;맞아. AWS는 TLS 1.0 / 1.1은 EOS(지원 종료) 때렸어.&lt;/b&gt;&lt;br /&gt;지금은 TLS 1.2 이상만 기본적으로 허용돼.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;1011&quot; data-start=&quot;997&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1097&quot; data-start=&quot;1073&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;그런데 여기서 중요한 말이 하나 더 나왔다:&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-end=&quot;1162&quot; data-start=&quot;1099&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;1162&quot; data-start=&quot;1101&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;&lt;b&gt;근데 그거 완전 차단은 아냐.&lt;/b&gt;&lt;br /&gt;일부 서비스는 설정에 따라 1.0 / 1.1도 쓸 수는 있어.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote data-end=&quot;1261&quot; data-start=&quot;1164&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;1261&quot; data-start=&quot;1166&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;&lt;b&gt;그러니까 반은 진짜고, 반은 귀찮아서 안 해주는 걸 수도 있어.&lt;/b&gt;&lt;br /&gt;TLS 낮췄다가 보안 사고 나면 누가 책임질 거야?&lt;br /&gt;나라도 그냥 안 내려줬을 듯.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&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;br /&gt;&lt;b&gt;기술적으로 가능하더라도&lt;/b&gt;&lt;br /&gt;정책상, 혹은 책임 회피성으로&lt;br /&gt;&lt;b&gt;&amp;ldquo;지원 못 합니다&amp;rdquo;라고 단답하는 경우도 있다는 것.&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;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;   결국, 우리 팀이 바꿨다&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;1473&quot; data-start=&quot;1398&quot; data-ke-size=&quot;size16&quot;&gt;협력사 쪽에선 TLS 버전 하향이 어렵다는 입장이었고&lt;br /&gt;우리 시스템은 Java 1.7이었기 때문에 TLS 1.2를 지원하지 않았다.&lt;/p&gt;
&lt;p data-end=&quot;1473&quot; data-start=&quot;1398&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1517&quot; data-start=&quot;1475&quot; data-ke-size=&quot;size16&quot;&gt;그래서 &lt;b&gt;결국 우리 팀에서 JDK를 1.8로 업그레이드하기로 결정했다.&lt;/b&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;style6&quot; /&gt;
&lt;p data-end=&quot;1268&quot; data-start=&quot;1246&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1499&quot; data-start=&quot;1478&quot; data-ke-size=&quot;size16&quot;&gt;물론 단순히 버전만 바꾸는 게 아니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1558&quot; data-start=&quot;1501&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1518&quot; data-start=&quot;1501&quot;&gt;테스트 환경까지 싹 점검&lt;/li&gt;
&lt;li data-end=&quot;1537&quot; data-start=&quot;1519&quot;&gt;라이브러리 버전 호환 확인&lt;/li&gt;
&lt;li data-end=&quot;1558&quot; data-start=&quot;1538&quot;&gt;운영 반영 및 배포 프로세스 조정&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1580&quot; data-start=&quot;1560&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;쉽지 않았지만, 해야만 했다.&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-end=&quot;1619&quot; data-start=&quot;1582&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;1619&quot; data-start=&quot;1584&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;보안도 중요하고, 협력사와 통신되는 게 더 중요했으니까.&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;1373&quot; data-start=&quot;1319&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1373&quot; data-start=&quot;1319&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;1389&quot; data-start=&quot;1380&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;✅ 정리하며&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;1758&quot; data-start=&quot;1701&quot; data-ke-size=&quot;size16&quot;&gt;이번 일을 겪은 우리 팀은&lt;br /&gt;&amp;ldquo;&lt;b&gt;통신이 안 될 땐 TLS부터 의심하자&amp;rdquo;&lt;/b&gt;는 교훈을 확실히 얻었다.&lt;/p&gt;
&lt;p data-end=&quot;1758&quot; data-start=&quot;1701&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1821&quot; data-start=&quot;1760&quot; data-ke-size=&quot;size16&quot;&gt;특히 &lt;b&gt;레거시 환경을 운영 중이라면&lt;/b&gt;&lt;br /&gt;&lt;b&gt;TLS 버전과 JDK 버전&lt;/b&gt;을 항상 인지하고 있어야 한다.&lt;/p&gt;
&lt;p data-end=&quot;1486&quot; data-start=&quot;1445&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1486&quot; data-start=&quot;1445&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;1762&quot; data-start=&quot;1747&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  실무 핵심 요약&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1885&quot; data-start=&quot;1764&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1792&quot; data-start=&quot;1764&quot;&gt;Java 1.7 &amp;rarr; TLS 1.2 지원 불가&lt;/li&gt;
&lt;li data-end=&quot;1820&quot; data-start=&quot;1793&quot;&gt;AWS &amp;rarr; TLS 1.2 이상만 기본 허용&lt;/li&gt;
&lt;li data-end=&quot;1851&quot; data-start=&quot;1821&quot;&gt;협력사 &amp;rarr; &amp;ldquo;내려줄 수 없음&amp;rdquo; (응. 안 해줌)&lt;/li&gt;
&lt;li data-end=&quot;1885&quot; data-start=&quot;1852&quot;&gt;해결책 &amp;rarr; JDK 1.8 업그레이드로 TLS 1.2 대응&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1486&quot; data-start=&quot;1445&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1486&quot; data-start=&quot;1445&quot; data-ke-size=&quot;size16&quot;&gt;그리고 이건 단순한 기술 이슈가 아니었다.&lt;br /&gt;&lt;b&gt;우리 시스템 구조에 대한 인식을 바꾼 계기&lt;/b&gt;이기도 했다.&lt;/p&gt;
&lt;p data-end=&quot;1486&quot; data-start=&quot;1445&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1486&quot; data-start=&quot;1445&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1486&quot; data-start=&quot;1445&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>트러블슈팅</category>
      <category>API연동</category>
      <category>AWS</category>
      <category>java17</category>
      <category>jdk업그레이드</category>
      <category>tls</category>
      <category>tls호환성</category>
      <category>레거시개발</category>
      <category>보안정책</category>
      <category>실무트러블슈팅</category>
      <category>커머스api</category>
      <author>리신</author>
      <guid isPermaLink="true">https://dev-cini.tistory.com/95</guid>
      <comments>https://dev-cini.tistory.com/95#entry95comment</comments>
      <pubDate>Fri, 25 Apr 2025 00:00:48 +0900</pubDate>
    </item>
    <item>
      <title>캐시는 빠르다! 근데 터지면 진짜 다 같이 죽는다!</title>
      <link>https://dev-cini.tistory.com/94</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zfBv7/btsNsddITHF/VzoNpSPmM8cCcMF9SjddIK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zfBv7/btsNsddITHF/VzoNpSPmM8cCcMF9SjddIK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zfBv7/btsNsddITHF/VzoNpSPmM8cCcMF9SjddIK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzfBv7%2FbtsNsddITHF%2FVzoNpSPmM8cCcMF9SjddIK%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;1024&quot; height=&quot;1024&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-end=&quot;136&quot; data-start=&quot;119&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;136&quot; data-start=&quot;119&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;☠️ 캐시 서버가 터졌다&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;211&quot; data-start=&quot;138&quot; data-ke-size=&quot;size16&quot;&gt;그날 진짜... 아무 생각 없이 평소처럼 일하고 있었는데&lt;br /&gt;갑자기 &lt;b&gt;&amp;ldquo;사이트 접속이 안 된다&amp;rdquo;&lt;/b&gt;는 연락이 여기저기서 쏟아졌다.&lt;/p&gt;
&lt;p data-end=&quot;211&quot; data-start=&quot;138&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;277&quot; data-start=&quot;213&quot; data-ke-size=&quot;size16&quot;&gt;싸늘하다.&lt;br /&gt;팀장급들과 윗분들 다 모여서 &lt;b&gt;한 화면만 보고 있다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;277&quot; data-start=&quot;213&quot; data-ke-size=&quot;size16&quot;&gt;그 화면 = 접속 불가된 우리 서비스.&lt;/p&gt;
&lt;p data-end=&quot;277&quot; data-start=&quot;213&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;313&quot; data-start=&quot;284&quot; data-ke-size=&quot;size16&quot;&gt;커머스 회사에서&amp;hellip;&lt;br /&gt;&lt;b&gt;사이트 접속이 안 됐다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;324&quot; data-start=&quot;315&quot; data-ke-size=&quot;size16&quot;&gt;그게 가능하냐고?&lt;/p&gt;
&lt;p data-end=&quot;331&quot; data-start=&quot;326&quot; data-ke-size=&quot;size16&quot;&gt;가능했다.&lt;/p&gt;
&lt;p data-end=&quot;331&quot; data-start=&quot;326&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;331&quot; data-start=&quot;326&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;347&quot; data-start=&quot;338&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;원인?&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-end=&quot;392&quot; data-start=&quot;348&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;392&quot; data-start=&quot;350&quot; data-ke-size=&quot;size16&quot;&gt;캐시 서버 터짐.&lt;br /&gt;진짜로. &lt;b&gt;그 한 놈 때문에 전체가 무너졌다.&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&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;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;142&quot; data-start=&quot;114&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  터진 이유는? 솔직히 아직도 잘 모른다&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;179&quot; data-start=&quot;144&quot; data-ke-size=&quot;size16&quot;&gt;지금 생각해보면&amp;hellip;&lt;/p&gt;
&lt;p data-end=&quot;179&quot; data-start=&quot;144&quot; data-ke-size=&quot;size16&quot;&gt;원인은 이 중 하나거나 전부였을지도 모른다..&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;459&quot; data-start=&quot;181&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;247&quot; data-start=&quot;181&quot;&gt;  &lt;b&gt;메모리 초과 (OOM)&lt;/b&gt;&lt;br /&gt;&amp;rarr; 캐시 TTL 안 걸려 있던 거 다 모여서 메모리 꽉 찼을 가능성 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;459&quot; data-start=&quot;181&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;315&quot; data-start=&quot;249&quot;&gt;  &lt;b&gt;동시에 대량 캐시 MISS&lt;/b&gt;&lt;br /&gt;&amp;rarr; 한 타이밍에 요청 몰려서 캐시 못 받고 DB로 몰렸을 수도 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;459&quot; data-start=&quot;181&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;374&quot; data-start=&quot;317&quot;&gt;❌ &lt;b&gt;캐시 삭제 실수?&lt;/b&gt;&lt;br /&gt;&amp;rarr; 배치든, 코드든, 누가 잘못해서 TTL 싹 날렸을 수도 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;459&quot; data-start=&quot;181&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;459&quot; data-start=&quot;376&quot;&gt;  &lt;b&gt;그냥 캐시 구조가 엉망이라?&lt;/b&gt;&lt;br /&gt;&amp;rarr; 캐시 키 관리도 없고, 갱신 로직도 없고&amp;hellip;&lt;br /&gt;그냥 다들 막 썼다. 진짜로. &lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;551&quot; data-start=&quot;501&quot; data-ke-size=&quot;size16&quot;&gt;사실 로그도 제대로 안 남았고, 추적도 힘들었다.&lt;br /&gt;&lt;b&gt;근데 분위기로는 다들 알았다.&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-end=&quot;580&quot; data-start=&quot;553&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;580&quot; data-start=&quot;555&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;이건&amp;hellip; 캐시를 너무 아무렇게나 썼던 거다.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&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;br /&gt;&lt;b&gt;가이드도 없이, 기준도 없이, 상황도 모르고&lt;/b&gt;&lt;br /&gt;그냥 &quot;느리다&quot; &amp;rarr; &quot;캐시 써요~&quot; 해서 붙였고..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;결국 그렇게 누적된 것들이&lt;/b&gt;&lt;br /&gt;한날한시에&amp;hellip; &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;팡.&lt;/b&gt; &lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-end=&quot;897&quot; data-start=&quot;877&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;897&quot; data-start=&quot;877&quot; 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-end=&quot;953&quot; data-start=&quot;899&quot; data-ke-size=&quot;size16&quot;&gt;우리 회사는 커머스 회사다.&lt;br /&gt;고객이 원하는 건 &lt;b&gt;지금, 바로, 눈앞에서 처리되는 서비스.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;953&quot; data-start=&quot;899&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;962&quot; data-start=&quot;955&quot; data-ke-size=&quot;size16&quot;&gt;근데 현실은?&lt;/p&gt;
&lt;p data-end=&quot;975&quot; data-start=&quot;964&quot; data-ke-size=&quot;size16&quot;&gt;현업은 이렇게 온다:&lt;/p&gt;
&lt;blockquote data-end=&quot;1065&quot; data-start=&quot;977&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;1065&quot; data-start=&quot;979&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;기능 만들어줘잉~ 화면 만들어줘잉~&amp;rdquo;&lt;br /&gt;그리고 1분 뒤엔 결재 올라가 있다.&lt;br /&gt;오픈일자까지 다 정해져 있음.&lt;br /&gt;개발자한테 말도 안 하고.&lt;/p&gt;
&lt;/blockquote&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-end=&quot;1086&quot; data-start=&quot;1072&quot; data-ke-size=&quot;size16&quot;&gt;그럼 개발은 어떻게 되냐?&lt;/p&gt;
&lt;p data-end=&quot;1103&quot; data-start=&quot;1088&quot; data-ke-size=&quot;size16&quot;&gt;  그냥 &lt;b&gt;막 한다.&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1167&quot; data-start=&quot;1105&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1125&quot; data-start=&quot;1105&quot;&gt;시니어, 주니어 가릴 것 없이&lt;/li&gt;
&lt;li data-end=&quot;1155&quot; data-start=&quot;1126&quot;&gt;일단 만들고 &amp;rarr; 바로 붙이고 &amp;rarr; 테스트는 내일&lt;/li&gt;
&lt;li data-end=&quot;1167&quot; data-start=&quot;1156&quot;&gt;그리고 오늘 오픈&lt;/li&gt;
&lt;/ul&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;style6&quot; /&gt;
&lt;p data-end=&quot;1198&quot; data-start=&quot;1174&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1198&quot; data-start=&quot;1174&quot; data-ke-size=&quot;size16&quot;&gt;그러다 어느 날&lt;br /&gt;현업이 이렇게 말한다:&lt;/p&gt;
&lt;blockquote data-end=&quot;1223&quot; data-start=&quot;1200&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;1223&quot; data-start=&quot;1202&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;상품 사진 느려요! 빨리 뜨게 해주세요!&amp;rdquo;&lt;br /&gt;&quot;상품이 안 뜨잖아요!!&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;1239&quot; data-start=&quot;1225&quot; data-ke-size=&quot;size16&quot;&gt;그리고 개발자는 고민한다:&lt;/p&gt;
&lt;blockquote data-end=&quot;1258&quot; data-start=&quot;1241&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;1258&quot; data-start=&quot;1243&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;그럼&amp;hellip; 캐시 써야겠네요&amp;hellip;&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;1280&quot; data-start=&quot;1260&quot; data-ke-size=&quot;size16&quot;&gt;그리고 그냥 &lt;b&gt;막&amp;hellip; 막&amp;hellip; 쓴다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1280&quot; data-start=&quot;1260&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1293&quot; data-start=&quot;1287&quot; data-ke-size=&quot;size16&quot;&gt;그 결과는?&lt;/p&gt;
&lt;p data-end=&quot;1303&quot; data-start=&quot;1295&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;터진다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;1303&quot; data-start=&quot;1295&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1303&quot; data-start=&quot;1295&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-end=&quot;1338&quot; data-start=&quot;1310&quot; data-ke-size=&quot;size26&quot;&gt; &amp;zwj;  그 이후 우리 팀장은 이렇게 말했다&lt;/h2&gt;
&lt;blockquote data-end=&quot;1403&quot; data-start=&quot;1340&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;1403&quot; data-start=&quot;1342&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;&lt;b&gt;캐시 쓸 거면 나한테 먼저 말하고 써.&lt;/b&gt;&lt;br /&gt;그냥 붙이지 마.&lt;br /&gt;또 그날처럼 되는 수 있어.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&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;style6&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;✅ 캐시는 빠르다, 하지만 위험하다&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&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;style2&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50.1163%;&quot;&gt;캐시 장점&lt;/td&gt;
&lt;td style=&quot;width: 49.8837%;&quot;&gt;캐시 단점&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50.1163%;&quot;&gt;빠르다 (메모리 기반)&lt;/td&gt;
&lt;td style=&quot;width: 49.8837%;&quot;&gt;휘발성, 데이터 유실 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50.1163%;&quot;&gt;DB 부하 줄임&lt;/td&gt;
&lt;td style=&quot;width: 49.8837%;&quot;&gt;캐시 MISS 몰리면 오리혀 DB 터짐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50.1163%;&quot;&gt;실시간 UX 개선&lt;/td&gt;
&lt;td style=&quot;width: 49.8837%;&quot;&gt;TLT/갱신 잘못 잡으면 장애 발생&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50.1163%;&quot;&gt;응답속도 향상&lt;/td&gt;
&lt;td style=&quot;width: 49.8837%;&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;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;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;1633&quot; data-start=&quot;1624&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  마무리&lt;/b&gt;&lt;/h3&gt;
&lt;blockquote data-end=&quot;1706&quot; data-start=&quot;1635&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;1669&quot; data-start=&quot;1637&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;캐시는 칼이다.&lt;/b&gt;&lt;br /&gt;잘 쓰면 빠르고 멋지다.&lt;/p&gt;
&lt;p data-end=&quot;1706&quot; data-start=&quot;1676&quot; data-ke-size=&quot;size16&quot;&gt;근데 잘못 쓰면&amp;hellip;&lt;br /&gt;&lt;b&gt;진짜 다 같이 죽는다.&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1740&quot; data-start=&quot;1714&quot; data-ke-size=&quot;size16&quot;&gt;그리고 그날 이후&lt;/p&gt;
&lt;p data-end=&quot;1740&quot; data-start=&quot;1714&quot; data-ke-size=&quot;size16&quot;&gt;모두가 마음속으로 인정했다.&lt;/p&gt;
&lt;blockquote data-end=&quot;1769&quot; data-start=&quot;1742&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;1769&quot; data-start=&quot;1744&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;ldquo;캐시를 너무 난발해서 쓴 게 문제였다.&amp;rdquo;&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&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-end=&quot;310&quot; data-start=&quot;275&quot; data-ke-size=&quot;size16&quot;&gt;터진 서버는&amp;hellip;&lt;br /&gt;알고 보니 &lt;b&gt;엄청 오래된 캐시 서버&lt;/b&gt;였다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;351&quot; data-start=&quot;312&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;326&quot; data-start=&quot;312&quot;&gt;물리 장비는 낡았고&lt;/li&gt;
&lt;li data-end=&quot;339&quot; data-start=&quot;327&quot;&gt;증설도 안 됐고&lt;/li&gt;
&lt;li data-end=&quot;351&quot; data-start=&quot;340&quot;&gt;모니터링도 없었다&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;404&quot; data-start=&quot;358&quot; data-ke-size=&quot;size16&quot;&gt;결국 우리는 중요한 캐시들은&lt;br /&gt;&lt;b&gt;하나씩 Redis로 옮기는 작업&lt;/b&gt;을 시작했다.&lt;/p&gt;
&lt;p data-end=&quot;447&quot; data-start=&quot;406&quot; data-ke-size=&quot;size16&quot;&gt;그리고 그 이후로&lt;br /&gt;&lt;b&gt;우리의 캐시에 대한 태도는 완전히 달라졌다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;447&quot; data-start=&quot;406&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-end=&quot;447&quot; data-start=&quot;406&quot; data-ke-style=&quot;style2&quot;&gt;&amp;ldquo;빠르니까 쓴다&amp;rdquo;&lt;br /&gt;&amp;rarr;&lt;br /&gt;&lt;b&gt;&amp;ldquo;책임질 수 있을 때만 쓴다&amp;rdquo; &lt;/b&gt;&lt;/blockquote&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>트러블슈팅</category>
      <category>백엔드이슈</category>
      <category>서버터짐</category>
      <category>시스템장애</category>
      <category>실무개발</category>
      <category>웹성능</category>
      <category>캐시사용주의</category>
      <category>캐시서버</category>
      <category>트러블슈팅</category>
      <author>리신</author>
      <guid isPermaLink="true">https://dev-cini.tistory.com/94</guid>
      <comments>https://dev-cini.tistory.com/94#entry94comment</comments>
      <pubDate>Thu, 24 Apr 2025 00:00:59 +0900</pubDate>
    </item>
    <item>
      <title>[Oracle]  오라클 시퀀스 초기화 3가지 방법</title>
      <link>https://dev-cini.tistory.com/93</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zDfji/btsNryCGF43/Oq7rNz6USV1PMM1WyWSxa0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zDfji/btsNryCGF43/Oq7rNz6USV1PMM1WyWSxa0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zDfji/btsNryCGF43/Oq7rNz6USV1PMM1WyWSxa0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzDfji%2FbtsNryCGF43%2FOq7rNz6USV1PMM1WyWSxa0%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;1024&quot; height=&quot;1024&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-end=&quot;244&quot; data-start=&quot;219&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;140&quot; data-start=&quot;115&quot; 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-end=&quot;205&quot; data-start=&quot;142&quot; data-ke-size=&quot;size16&quot;&gt;개발하다 보면 종종&lt;br /&gt;테스트 데이터를 모두 삭제하고&lt;br /&gt;&lt;b&gt;시퀀스도 다시 1부터 시작하고 싶을 때&lt;/b&gt;가 있다.&lt;/p&gt;
&lt;p data-end=&quot;205&quot; data-start=&quot;142&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;277&quot; data-start=&quot;207&quot; data-ke-size=&quot;size16&quot;&gt;나도 INSERT 테스트 몇 번 하고 DELETE로 비웠는데&lt;br /&gt;시퀀스는 계속 101, 102... 이렇게 올라가 있어서&lt;/p&gt;
&lt;blockquote data-end=&quot;320&quot; data-start=&quot;278&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;320&quot; data-start=&quot;280&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;이거 다시 1부터 못 돌리나?&amp;rdquo;&lt;br /&gt;싶어서 한참 찾아봤던 기억이 있다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;391&quot; data-start=&quot;322&quot; data-ke-size=&quot;size16&quot;&gt;그래서 정리했다.&lt;/p&gt;
&lt;p data-end=&quot;391&quot; data-start=&quot;322&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;Oracle에서 시퀀스를 초기화하는 3가지 방법&lt;/b&gt;&lt;br /&gt;&lt;b&gt;가장 많이 쓰는 기준&lt;/b&gt;으로!&lt;/p&gt;
&lt;p data-end=&quot;391&quot; data-start=&quot;322&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;391&quot; data-start=&quot;322&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;456&quot; data-start=&quot;398&quot; data-ke-size=&quot;size16&quot;&gt;❗ 그리고 참고로&lt;br /&gt;&lt;b&gt;운영에서 시퀀스 초기화하면&amp;hellip; 크으으으은일 납니다&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;456&quot; data-start=&quot;398&quot; data-ke-size=&quot;size16&quot;&gt;운영 시퀀스 건드릴 수도 없겠지만 혹시나 하는 마음에 ㅎ&lt;br /&gt;(진짜 PK 충돌나서 난리부르스 서비스 에러에러에러 voc voc voc... ++;)&lt;/p&gt;
&lt;p data-end=&quot;492&quot; data-start=&quot;458&quot; data-ke-size=&quot;size16&quot;&gt;  이건 어디까지나 &lt;b&gt;개발 서버 기준에서만&lt;/b&gt; 사용하세요!&lt;/p&gt;
&lt;p data-end=&quot;492&quot; data-start=&quot;458&quot; 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;style6&quot; /&gt;
&lt;p data-end=&quot;492&quot; data-start=&quot;458&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;492&quot; data-start=&quot;458&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt; 1. 기존 시퀀스 삭제 후 새로 생성 (가장 깔끔함)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가장 확실한 방법은 &lt;b&gt;DROP 후 CREATE&lt;/b&gt; 하는 것.&lt;/p&gt;
&lt;pre id=&quot;code_1745124369298&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;DROP SEQUENCE MY_SEQ;

CREATE SEQUENCE MY_SEQ
START WITH 1
INCREMENT BY 1
NOCACHE;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;681&quot; data-start=&quot;656&quot;&gt;START WITH로 초기값 설정 가능&lt;/li&gt;
&lt;li data-end=&quot;711&quot; data-start=&quot;682&quot;&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;✅ &lt;b&gt;단점:&lt;/b&gt; 기존 시퀀스를 참조하던 트리거나 외부 객체가 있을 경우&lt;br /&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-end=&quot;433&quot; data-start=&quot;419&quot; data-ke-size=&quot;size16&quot;&gt;❗ &lt;b&gt;더더더 주의!!&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;491&quot; data-start=&quot;435&quot; data-ke-size=&quot;size16&quot;&gt;이건 내가 &lt;b&gt;개발하려고 새로 만든 시퀀스&lt;/b&gt;다!&lt;br /&gt;= &lt;b&gt;내가 소유권 100%&lt;/b&gt;일 때만 쓰세요.&lt;/p&gt;
&lt;p data-end=&quot;491&quot; data-start=&quot;435&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;491&quot; data-start=&quot;435&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;521&quot; data-start=&quot;493&quot; data-ke-size=&quot;size16&quot;&gt;  아래와 같은 시퀀스는 절대 함부로 삭제 금지:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;563&quot; data-start=&quot;522&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;540&quot; data-start=&quot;522&quot;&gt;남들도 같이 쓰는 공용 시퀀스&lt;/li&gt;
&lt;li data-end=&quot;563&quot; data-start=&quot;541&quot;&gt;운영 중 실시간으로 참조 중인 시퀀스&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-end=&quot;594&quot; data-start=&quot;565&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;594&quot; data-start=&quot;567&quot; data-ke-size=&quot;size16&quot;&gt;그런 거 건드리면&amp;hellip; &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;호호호호혼. 남.&lt;/span&gt;  &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&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;style6&quot; /&gt;
&lt;h4 data-end=&quot;792&quot; data-start=&quot;756&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. ALTER로 NEXTVAL 조정 (간단하지만 제한적)&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1745124786463&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;-- 현재 시퀀스 값보다 낮게 설정하고 싶으면
-- INCREMENT 값을 일시적으로 조정한 후 한번 호출
ALTER SEQUENCE MY_SEQ INCREMENT BY -99;
SELECT MY_SEQ.NEXTVAL FROM DUAL; -- (예: 현재 100 &amp;rarr; 1로 맞추기)
ALTER SEQUENCE MY_SEQ INCREMENT BY 1;&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1018&quot; data-start=&quot;1001&quot;&gt;현재 값 기준으로 상대 조정&lt;/li&gt;
&lt;li data-end=&quot;1045&quot; data-start=&quot;1019&quot;&gt;정확히 몇까지 올라갔는지 알고 있어야 가능함&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&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;style6&quot; /&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; 3. RESTART 옵션 사용 (Oracle 12c 이상)&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1745124821061&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;ALTER SEQUENCE MY_SEQ RESTART START WITH 1;&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1208&quot; data-start=&quot;1169&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1186&quot; data-start=&quot;1169&quot;&gt;오라클 12c 이상부터 가능&lt;/li&gt;
&lt;li data-end=&quot;1208&quot; data-start=&quot;1187&quot;&gt;가장 간단하게 &amp;ldquo;다시 1부터 시작&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1230&quot; data-start=&quot;1210&quot; data-ke-size=&quot;size16&quot;&gt;❗&lt;b&gt; 단점:&lt;/b&gt; 구버전에서는 동작하지 않음&lt;/p&gt;
&lt;p data-end=&quot;1230&quot; data-start=&quot;1210&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1230&quot; data-start=&quot;1210&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1230&quot; data-start=&quot;1210&quot; 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;style6&quot; /&gt;
&lt;h3 data-end=&quot;147&quot; data-start=&quot;127&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  실제로 나는 이렇게 했음&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;227&quot; data-start=&quot;149&quot; data-ke-size=&quot;size16&quot;&gt;처음엔 몰랐어서...&lt;br /&gt;그냥 &lt;span style=&quot;background-color: #dddddd;&quot;&gt;SELECT MY_SEQ.NEXTVAL FROM DUAL;&lt;/span&gt;&lt;br /&gt;계속 호출하면서 시퀀스를 올렸었다&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;227&quot; data-start=&quot;149&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-end=&quot;227&quot; data-start=&quot;149&quot; data-ke-style=&quot;style2&quot;&gt;나란놈은 개발자 맞냐..?&amp;nbsp;  &amp;zwj; &lt;/blockquote&gt;
&lt;p data-end=&quot;227&quot; data-start=&quot;149&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;279&quot; data-start=&quot;229&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;279&quot; data-start=&quot;229&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&quot;뭔가 아닌데&amp;hellip;&quot;&lt;/b&gt; 싶었지만&lt;br /&gt;그때는 다른 방법을 몰랐어서 계속 눌렀음. 진짜로.&lt;/p&gt;
&lt;p data-end=&quot;279&quot; data-start=&quot;229&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;347&quot; data-start=&quot;281&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;347&quot; data-start=&quot;281&quot; data-ke-size=&quot;size16&quot;&gt;결국 검색 끝에&lt;br /&gt;&lt;b&gt;DROP 후 CREATE로 초기화하는 방식&lt;/b&gt;을 알게 됐고&lt;br /&gt;그 방법으로 깔끔하게 리셋했다.&lt;/p&gt;
&lt;p data-end=&quot;347&quot; data-start=&quot;281&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;412&quot; data-start=&quot;349&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;412&quot; data-start=&quot;349&quot; data-ke-size=&quot;size16&quot;&gt;물론 나는 테스트 환경이라 괜찮았지만&lt;br /&gt;&lt;b&gt;실제 운영 환경이었다면 트리거나 의존성 문제로 사고 남&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;412&quot; data-start=&quot;349&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;412&quot; data-start=&quot;349&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;412&quot; data-start=&quot;349&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;445&quot; data-start=&quot;427&quot; data-ke-size=&quot;size16&quot;&gt;  &lt;b&gt;운영 환경이라면?&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-end=&quot;480&quot; data-start=&quot;446&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;480&quot; data-start=&quot;448&quot; data-ke-size=&quot;size16&quot;&gt;그냥 하지 말고 &lt;b&gt;무조건 DBA한테 먼저 의논하세요!!!&lt;br /&gt;&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;412&quot; data-start=&quot;349&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;412&quot; data-start=&quot;349&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;412&quot; data-start=&quot;349&quot; data-ke-size=&quot;size16&quot;&gt;⚠️ &lt;b&gt;신규 개발로 만든 시퀀스가 아닌데도 손댄다?&lt;/b&gt;&lt;br /&gt;&amp;rarr; 개발에서도 조심해야 함&lt;br /&gt;&amp;rarr; &lt;b&gt;잘못 건드리면 진짜 욕.먹.음.&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;412&quot; data-start=&quot;349&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;412&quot; data-start=&quot;349&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;427&quot; data-start=&quot;414&quot; data-ke-size=&quot;size16&quot;&gt;그래서 꼭 말하고 싶다:&lt;/p&gt;
&lt;blockquote data-end=&quot;499&quot; data-start=&quot;428&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;499&quot; data-start=&quot;430&quot; data-ke-size=&quot;size16&quot;&gt;  &lt;b&gt;DROP 방식은 정말 내가 신규로 개발하기 위해 만든 시퀀스일 때만.&lt;/b&gt;&lt;br /&gt;  &lt;b&gt;그리고 의존성 확인은 무조건 먼저 해야 함!&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DataBase/Oracle</category>
      <category>altersequence</category>
      <category>dropsequence</category>
      <category>restartsequence</category>
      <category>sql정리</category>
      <category>백엔드개발</category>
      <category>시퀀스초기화</category>
      <category>오라클시퀀스</category>
      <category>오라클시퀀스초기화</category>
      <author>리신</author>
      <guid isPermaLink="true">https://dev-cini.tistory.com/93</guid>
      <comments>https://dev-cini.tistory.com/93#entry93comment</comments>
      <pubDate>Wed, 23 Apr 2025 00:00:42 +0900</pubDate>
    </item>
    <item>
      <title>SVN 커밋이 안 될 때 점검할 3가지</title>
      <link>https://dev-cini.tistory.com/92</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfg6VS/btsNs4GmvrW/Yv4a7DBGzgbXX4r1seFctk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfg6VS/btsNs4GmvrW/Yv4a7DBGzgbXX4r1seFctk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfg6VS/btsNs4GmvrW/Yv4a7DBGzgbXX4r1seFctk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbfg6VS%2FbtsNs4GmvrW%2FYv4a7DBGzgbXX4r1seFctk%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;1024&quot; height=&quot;1024&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;244&quot; data-start=&quot;217&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;SVN 커밋이 안 될 때 실제로 겪은 상황&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;302&quot; data-start=&quot;246&quot; data-ke-size=&quot;size16&quot;&gt;SVN으로 소스 관리를 하다 보면&lt;br /&gt;&lt;b&gt;어느 날 갑자기 커밋이 안 되는 프로젝트가 생기곤 한다... 개빡침..&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;302&quot; data-start=&quot;246&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;391&quot; data-start=&quot;304&quot; data-ke-size=&quot;size16&quot;&gt;나도 똑같은 이클립스 환경 같은 SVN 리포지토리에서&lt;br /&gt;&lt;b&gt;A 프로젝트는 정상 커밋이 되는데, B 프로젝트는 아무 반응 없이 실패하는 상황&lt;/b&gt;을 겪었다.&lt;/p&gt;
&lt;p data-end=&quot;391&quot; data-start=&quot;304&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;429&quot; data-start=&quot;393&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&quot;설정이 다른 것도 아닌데, 왜 이 프로젝트만 안 되지?&quot;&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;484&quot; data-start=&quot;431&quot; data-ke-size=&quot;size16&quot;&gt;결국 확인해보니, 원인은 &lt;b&gt;파일 잠금(Lock) 상태&lt;/b&gt;와 &lt;b&gt;숨겨진 설정 차이&lt;/b&gt;에 있었다.&lt;/p&gt;
&lt;p data-end=&quot;484&quot; data-start=&quot;431&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-end=&quot;484&quot; data-start=&quot;431&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; 1. 파일이 lock 상태인지 확인해보기&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;639&quot; data-start=&quot;519&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;551&quot; data-start=&quot;519&quot;&gt;SVN은 파일을 lock(잠금) 상태로 지정할 수 있음&lt;/li&gt;
&lt;li data-end=&quot;639&quot; data-start=&quot;552&quot;&gt;누군가가 해당 파일을 Lock 해두었거나, 내가 Lock 후 Release 안 했을 경우&lt;br /&gt;&amp;rarr; &lt;b&gt;커밋 시도해도 아무 반응 없이 멈춤&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;649&quot; data-start=&quot;641&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅ 해결 방법:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;770&quot; data-start=&quot;650&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;719&quot; data-start=&quot;650&quot;&gt;TortoiseSVN 기준: 해당 파일 우클릭 &amp;rarr; &quot;Release lock&quot; 또는 &quot;Get Lock&quot;으로 상태 확인/변경&lt;/li&gt;
&lt;li data-end=&quot;770&quot; data-start=&quot;720&quot;&gt;이클립스 기준: Team &amp;rarr; Show Properties로 lock 정보 확인 가능&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 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; 2. SVN 상태 갱신 (Clean up)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;886&quot; data-start=&quot;806&quot; data-ke-size=&quot;size16&quot;&gt;때때로 &lt;b&gt;작업 중 SVN 메타정보가 꼬여서&lt;/b&gt; 커밋이 실패하는 경우도 많음&lt;br /&gt;이럴 땐 Clean up 기능으로 상태를 정리해줘야 함&lt;/p&gt;
&lt;p data-end=&quot;886&quot; data-start=&quot;806&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;896&quot; data-start=&quot;888&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅ 해결 방법:&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;996&quot; data-start=&quot;897&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;941&quot; data-start=&quot;897&quot;&gt;TortoiseSVN &amp;rarr; 프로젝트 폴더 우클릭 &amp;rarr; &quot;SVN Clean up&quot;&lt;/li&gt;
&lt;li data-end=&quot;996&quot; data-start=&quot;942&quot;&gt;&quot;Break locks&quot;, &quot;Include externals&quot; 등 체크박스 전부 체크 후 실행&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; 3. .svn/wc.db 내부 잠금 수동 삭제 (SQLite 활용)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1059&quot; data-start=&quot;971&quot; data-ke-size=&quot;size16&quot;&gt;모든 방법을 다 써도 안 되는 경우엔&lt;br /&gt;SVN 내부의 .svn/wc.db 파일을 직접 열어&lt;br /&gt;&lt;b&gt;잠금 정보를 SQLite로 삭제&lt;/b&gt;하는 방법이 있음&lt;/p&gt;
&lt;p data-end=&quot;1059&quot; data-start=&quot;971&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1143&quot; data-start=&quot;1061&quot; data-ke-size=&quot;size16&quot;&gt;이 파일은 SVN 워킹 카피의 내부 상태를 저장하는 SQLite DB인데&lt;br /&gt;잠금 정보가 LOCK 테이블에 남아 있으면 커밋이 막힐 수 있음&lt;/p&gt;
&lt;p data-end=&quot;1143&quot; data-start=&quot;1061&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1153&quot; data-start=&quot;1145&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;✅ 해결 방법:&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1153&quot; data-start=&quot;1145&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1153&quot; data-start=&quot;1145&quot; data-ke-size=&quot;size16&quot;&gt;1. .svn/wc.db 파일을 SQLite DB Browser 또는 SQLite CLI로 연다.&lt;/p&gt;
&lt;p data-end=&quot;1153&quot; data-start=&quot;1145&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1153&quot; data-start=&quot;1145&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;2. 현재 잠금 상태 확인&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1745079730480&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT * FROM LOCK;&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;3. 모든 잠금 삭제&lt;/p&gt;
&lt;pre id=&quot;code_1745079778139&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;DELETE FROM LOCK;&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;4. 저장 후 종료 &amp;rarr; 다시 커밋 시도&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Clean up이 안 통하던 상황에서 이 방법으로 커밋 문제를 해결한 적이 있음&lt;/blockquote&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-end=&quot;1414&quot; data-start=&quot;1402&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;✅ 마무리 요약&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;1521&quot; data-start=&quot;1416&quot; data-ke-size=&quot;size16&quot;&gt;SVN 커밋이 안 될 땐 당황하지 말고&lt;br /&gt;1️⃣ 파일 잠금 상태&lt;br /&gt;2️⃣ Clean up 여부&lt;br /&gt;3️⃣ .svn 내부 상태&lt;/p&gt;
&lt;p data-end=&quot;1521&quot; data-start=&quot;1416&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;이 3가지를 순서대로 점검해보면 대부분 해결된다.&lt;/p&gt;
&lt;p data-end=&quot;1521&quot; data-start=&quot;1416&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1591&quot; data-start=&quot;1523&quot; data-ke-size=&quot;size16&quot;&gt;특히 .svn/wc.db에 남아 있는 LOCK 정보는&lt;br /&gt;&lt;b&gt;커밋이 조용히 먹통 되는 원인 중 가장 찝찝한 놈&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-end=&quot;1591&quot; data-start=&quot;1523&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1591&quot; data-start=&quot;1523&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>기타/에러</category>
      <category>SQLite</category>
      <category>SVN</category>
      <category>svn커밋안됌</category>
      <category>svn커밋오류</category>
      <category>svn파일잠금</category>
      <category>버전관리</category>
      <category>소스관리</category>
      <author>리신</author>
      <guid isPermaLink="true">https://dev-cini.tistory.com/92</guid>
      <comments>https://dev-cini.tistory.com/92#entry92comment</comments>
      <pubDate>Tue, 22 Apr 2025 00:00:43 +0900</pubDate>
    </item>
    <item>
      <title>[트러블슈팅] DB 세션이란? 롱 아이들 세션이 쌓이면 생기는 진짜 문제</title>
      <link>https://dev-cini.tistory.com/91</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bATVs4/btsNsS7h5bC/amsKFjVe1bjVMzTna8D3Gk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bATVs4/btsNsS7h5bC/amsKFjVe1bjVMzTna8D3Gk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bATVs4/btsNsS7h5bC/amsKFjVe1bjVMzTna8D3Gk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbATVs4%2FbtsNsS7h5bC%2FamsKFjVe1bjVMzTna8D3Gk%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;1024&quot; height=&quot;1024&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;131&quot; data-start=&quot;57&quot; data-ke-size=&quot;size16&quot;&gt;원래는 &lt;b&gt;인터페이스로 통신해 해당 기능을 실행하던 구조&lt;/b&gt;였는데&lt;br /&gt;직접 시스템 자체에서 해당 기능을 처리하라는 요청이 들어왔다.&lt;/p&gt;
&lt;p data-end=&quot;131&quot; data-start=&quot;57&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;218&quot; data-start=&quot;133&quot; data-ke-size=&quot;size16&quot;&gt;급하게 대응하기 위해 &lt;b&gt;DB LINK를 신청해서 다른 DB에 INSERT&lt;/b&gt;하는 방식으로 로직을 변경했고&lt;br /&gt;단순한 작업이라 금방 끝냈다고 생각했다.&lt;/p&gt;
&lt;p data-end=&quot;218&quot; data-start=&quot;133&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;246&quot; data-start=&quot;220&quot; data-ke-size=&quot;size16&quot;&gt;그런데 바로 다음날 DBA팀에서 연락이 왔다.&lt;/p&gt;
&lt;blockquote data-end=&quot;290&quot; data-start=&quot;247&quot; data-ke-style=&quot;style1&quot;&gt;
&lt;p data-end=&quot;290&quot; data-start=&quot;249&quot; data-ke-size=&quot;size16&quot;&gt;&amp;ldquo;&lt;b&gt;해당 DB에 세션이 갑자기 급증했는데, 혹시 무슨 작업하셨어요?&lt;/b&gt;&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-end=&quot;362&quot; data-start=&quot;292&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;362&quot; data-start=&quot;292&quot; data-ke-size=&quot;size16&quot;&gt;확인해보니, &lt;b&gt;DB LINK를 통해 연결된 세션이 자동으로 닫히지 않아&lt;br /&gt;INACTIVE 상태로 계속 남아 있었던 것...&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;362&quot; data-start=&quot;292&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;437&quot; data-start=&quot;364&quot; data-ke-size=&quot;size16&quot;&gt;이 일을 계기로, &lt;b&gt;DB 세션과 롱 아이들 세션 이슈의 심각성&lt;/b&gt;을 처음 알게 되었고&lt;br /&gt;정리 차원에서 이 글을 작성하게 되었다.&lt;/p&gt;
&lt;p data-end=&quot;437&quot; data-start=&quot;364&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;437&quot; data-start=&quot;364&quot; 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;style6&quot; /&gt;
&lt;h3 data-end=&quot;437&quot; data-start=&quot;364&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt; DB 세션이란?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DB 세션은 클라이언트(자바 애플리케이션 등)가&lt;br /&gt;&lt;b&gt;DB에 접속할 때 생성되는 하나의 &lt;span style=&quot;color: #ee2323;&quot;&gt;연결 통로&lt;/span&gt;임&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;해당 세션을 통해 SQL 쿼리를 날리고 결과를 받아오며&lt;br /&gt;작업이 끝나면 &lt;b&gt;close() 등을 통해 명시적으로 종료해줘야 함&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-end=&quot;797&quot; data-start=&quot;763&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;롱 아이들 세션(Long Idle Session)이란?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;919&quot; data-start=&quot;799&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;세션이 열려&lt;/b&gt; 있지만 &lt;b&gt;아무 작업도 하지 않고 &lt;span style=&quot;color: #ee2323;&quot;&gt;오랫동안 남아있는 상태&lt;/span&gt;&lt;/b&gt;를 말함.&lt;/p&gt;
&lt;p data-end=&quot;919&quot; data-start=&quot;799&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;보통 INACTIVE, IDLE 상태라고 표현되며&lt;br /&gt;이 세션들도 여전히&lt;b&gt; DB 자원을 점유하고 있기 때문에 문제가 됨&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;919&quot; data-start=&quot;799&quot; 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;style6&quot; /&gt;
&lt;p data-end=&quot;919&quot; data-start=&quot;799&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;958&quot; data-start=&quot;926&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;DB LINK를 썼을 때 왜 이런 문제가 생겼을까?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;1076&quot; data-start=&quot;960&quot; data-ke-size=&quot;size16&quot;&gt;DB LINK는 하나의 DB에서 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;다른 DB로 직접 접근할 수 있는 기능&lt;/b&gt;&lt;/span&gt;임&lt;/p&gt;
&lt;p data-end=&quot;1076&quot; data-start=&quot;960&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;INSERT 쿼리 한 줄만 날리면 끝나는 것 같지만&lt;br /&gt;&lt;b&gt;실제로는 다음과 같은 이유로 세션이 정리되지 않고 쌓일 수 있음&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1209&quot; data-start=&quot;1078&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1106&quot; data-start=&quot;1078&quot;&gt;쿼리 실행 후 커밋/롤백을 명시적으로 하지 않음&lt;/li&gt;
&lt;li data-end=&quot;1146&quot; data-start=&quot;1107&quot;&gt;자바 코드에서 DB LINK로 연결된 커넥션을 직접 종료할 수 없음&lt;/li&gt;
&lt;li data-end=&quot;1180&quot; data-start=&quot;1147&quot;&gt;외부 DB에서 rollback을 기다리는 상태일 수 있음&lt;/li&gt;
&lt;li data-end=&quot;1209&quot; data-start=&quot;1181&quot;&gt;기능이 반복적으로 호출되면서 세션이 계속 누적됨&lt;/li&gt;
&lt;/ul&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;style6&quot; /&gt;
&lt;p data-end=&quot;919&quot; data-start=&quot;799&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-end=&quot;919&quot; data-start=&quot;799&quot; 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;style15&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 22.3256%;&quot;&gt;&lt;b&gt;방법&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 77.6744%;&quot;&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 22.3256%;&quot;&gt;&lt;b&gt;트랜잭션 명확히 처리&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 77.6744%;&quot;&gt;COMMIT 또는 ROLLBACK을 명시적으로 해줄 것&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 22.3256%;&quot;&gt;&lt;b&gt;DB LINK 사용 최소화&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 77.6744%;&quot;&gt;읽기 전용 쿼리는 괜찮지만 쓰기(INSERT/UPDATE)는 피할 것&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 22.3256%;&quot;&gt;&lt;b&gt;JNDI 방식으로 전환&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 77.6744%;&quot;&gt;자바 애플리케이션에서 직접 DB커넥션을 관리할 수 있어 세션 회수가 쉬움&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 22.3256%;&quot;&gt;&lt;b&gt;커넥션 풀 설정 튜닝&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 77.6744%;&quot;&gt;removeAbandoned=true, removeAbandonedTimeout 설정 등을 통해 미사용 커넥션 회수 가능&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;h4 data-end=&quot;494&quot; data-start=&quot;474&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;✅ 내가 실제로 해결한 방법&lt;/b&gt;&lt;/h4&gt;
&lt;p data-end=&quot;633&quot; data-start=&quot;496&quot; data-ke-size=&quot;size16&quot;&gt;필자는 DB LINK 방식에서 발생한 세션 누적 문제를 해결하기 위해&lt;br /&gt;&lt;b&gt;DB 연결 방식을 JNDI로 전환&lt;/b&gt;했다.&lt;/p&gt;
&lt;p data-end=&quot;633&quot; data-start=&quot;496&quot; data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;이렇게 하면 애플리케이션 레벨에서 커넥션을 직접 제어할 수 있고&lt;br /&gt;세션이 자동으로 관리되어 누수가 발생하지 않는다.&lt;/p&gt;
&lt;p data-end=&quot;633&quot; data-start=&quot;496&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;717&quot; data-start=&quot;635&quot; data-ke-size=&quot;size16&quot;&gt;다만, &lt;b&gt;직접 해당 DB에 INSERT를 수행해야 했고&lt;/b&gt;&lt;br /&gt;해당 DB는 사양이 낮은 편이어서 &lt;b&gt;TPS(Transactions Per Second)&lt;/b&gt;를 너무 높이지 않도록 주의가 필요했다.&lt;/p&gt;
&lt;p data-end=&quot;717&quot; data-start=&quot;635&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;809&quot; data-start=&quot;719&quot; data-ke-size=&quot;size16&quot;&gt;그래서 JNDI 설정 시&lt;br /&gt;&lt;b&gt;커넥션 풀의 maxActive 값도 의도적으로 낮게 조정&lt;/b&gt;해&lt;br /&gt;DB에 무리가 가지 않도록 설정했다.&lt;/p&gt;
&lt;p data-end=&quot;809&quot; data-start=&quot;719&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;809&quot; data-start=&quot;719&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;JNDI 설명 참고&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a title=&quot;JNDI란?&quot; href=&quot;https://dev-cini.tistory.com/90&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://dev-cini.tistory.com/90&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;809&quot; data-start=&quot;719&quot; 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;style6&quot; /&gt;
&lt;h3 data-end=&quot;1695&quot; data-start=&quot;1689&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;결론&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;1753&quot; data-start=&quot;1697&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;세션은&lt;/b&gt;&lt;/span&gt; 눈에 보이지 않지만&lt;br /&gt;&lt;b&gt;쌓이면 시스템에 큰 문제를 유발할 수 있는 중요한 자원임&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1753&quot; data-start=&quot;1697&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1829&quot; data-start=&quot;1755&quot; data-ke-size=&quot;size16&quot;&gt;DB LINK는 설정이 간단하다는 장점이 있지만&lt;br /&gt;&lt;b&gt;트랜잭션 관리와 세션 종료가 불확실해 세션 누적 문제가 자주 발생함&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1829&quot; data-start=&quot;1755&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1911&quot; data-start=&quot;1831&quot; data-ke-size=&quot;size16&quot;&gt;가능하다면&lt;br /&gt;&lt;b&gt;JNDI 기반 커넥션 풀 방식으로 DB를 연결하고&lt;/b&gt;&lt;br /&gt;&lt;b&gt;트랜잭션을 명확하게 종료하는 습관을 들이는 것이 좋음&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1911&quot; data-start=&quot;1831&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1911&quot; data-start=&quot;1831&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1911&quot; data-start=&quot;1831&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>트러블슈팅</category>
      <category>dblink문제</category>
      <category>db세션</category>
      <category>db트러블슈팅</category>
      <category>JNDI</category>
      <category>디비링크문제</category>
      <category>디비세션</category>
      <category>롱아이들세션</category>
      <category>세션관리</category>
      <category>실무개발팁</category>
      <category>커넥션풀</category>
      <author>리신</author>
      <guid isPermaLink="true">https://dev-cini.tistory.com/91</guid>
      <comments>https://dev-cini.tistory.com/91#entry91comment</comments>
      <pubDate>Mon, 21 Apr 2025 00:00:29 +0900</pubDate>
    </item>
    <item>
      <title>[JAVA] JNDI란 무엇인가? 그리고 언제 사용하는가?</title>
      <link>https://dev-cini.tistory.com/90</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bti5RT/btsNsRUNNVt/4Wjc0QLbocAO6aFBt6n2b1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bti5RT/btsNsRUNNVt/4Wjc0QLbocAO6aFBt6n2b1/img.png&quot; data-alt=&quot;Java 애플리케이션이 어떻게 DB와 연결되는지를 JNDI를 통해 흐름 순서대로 정리한 구조도&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bti5RT/btsNsRUNNVt/4Wjc0QLbocAO6aFBt6n2b1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbti5RT%2FbtsNsRUNNVt%2F4Wjc0QLbocAO6aFBt6n2b1%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;1024&quot; height=&quot;1024&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1024&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Java 애플리케이션이 어떻게 DB와 연결되는지를 JNDI를 통해 흐름 순서대로 정리한 구조도&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;JNDI란?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-end=&quot;368&quot; data-start=&quot;218&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;JNDI(Java Naming and Directory Interface)&lt;/b&gt; 는&lt;br /&gt;Java 기반 웹 애플리케이션에서 &lt;b&gt;DB 연결 정보(DataSource)&lt;/b&gt; 를 외부 설정으로 분리하고&lt;br /&gt;필요할 때 코드에서 &lt;b&gt;lookup 방식으로 꺼내 쓰는 기술&lt;/b&gt;임&lt;/p&gt;
&lt;p data-end=&quot;368&quot; data-start=&quot;218&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;447&quot; data-start=&quot;370&quot; data-ke-size=&quot;size16&quot;&gt;쉽게 말하면&lt;br /&gt;&lt;b&gt;&amp;ldquo;DB 접속 정보를 미리 서버(Tomcat 등)에 등록해두고 앱에서는 그냥 이름만 불러서 사용하는 방식&amp;rdquo;&lt;/b&gt;임&lt;/p&gt;
&lt;p data-end=&quot;447&quot; data-start=&quot;370&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;447&quot; data-start=&quot;370&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-end=&quot;447&quot; data-start=&quot;370&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt; 전체 흐름 한눈에 보기 (위 다이어그램 설명)&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;TOMCAT&amp;nbsp;설정&amp;nbsp;&amp;rarr;&amp;nbsp;JNDI에&amp;nbsp;DataSource&amp;nbsp;등록됨 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;darr; &lt;br /&gt;Java&amp;nbsp;Application이&amp;nbsp;JNDI에서&amp;nbsp;lookup() &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;darr; &lt;br /&gt;DataSource에서&amp;nbsp;Connection&amp;nbsp;꺼냄 &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;darr; &lt;br /&gt;DB에&amp;nbsp;쿼리&amp;nbsp;날림&lt;/blockquote&gt;
&lt;h4 data-end=&quot;411&quot; data-start=&quot;389&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;✅ 흐름 설명 (실제 동작 순서)&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;708&quot; data-start=&quot;413&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;489&quot; data-start=&quot;413&quot;&gt;&lt;b&gt;Tomcat&lt;/b&gt;에서 server.xml이나 context.xml에 &lt;b&gt;JNDI DataSource 설정&lt;/b&gt;을 해둠&lt;/li&gt;
&lt;li data-end=&quot;541&quot; data-start=&quot;490&quot;&gt;WAS가 실행되면 설정된 &lt;b&gt;JNDI 리소스가 등록됨&lt;/b&gt; (예: jdbc/myDB)&lt;/li&gt;
&lt;li data-end=&quot;619&quot; data-start=&quot;542&quot;&gt;&lt;b&gt;Java 코드에서 lookup(&quot;java:comp/env/jdbc/myDB&quot;) 호출&lt;/b&gt; &amp;rarr; 등록된 JNDI 리소스를 가져옴&lt;/li&gt;
&lt;li data-end=&quot;680&quot; data-start=&quot;620&quot;&gt;가져온 DataSource 객체에서 getConnection() 호출 &amp;rarr; &lt;b&gt;DB에 커넥션 연결&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;708&quot; data-start=&quot;681&quot;&gt;연결된 커넥션을 통해 &lt;b&gt;DB 작업 수행&lt;/b&gt;&lt;/li&gt;
&lt;/ol&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;style6&quot; /&gt;
&lt;h3 data-end=&quot;447&quot; data-start=&quot;370&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;447&quot; data-start=&quot;370&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;왜 필요한가?&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;643&quot; data-start=&quot;473&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;507&quot; data-start=&quot;473&quot;&gt;&lt;b&gt;보안&lt;/b&gt;: DB ID/PW를 코드에 직접 적지 않음&lt;/li&gt;
&lt;li data-end=&quot;551&quot; data-start=&quot;508&quot;&gt;&lt;b&gt;환경 분리&lt;/b&gt;: 개발/운영서버 환경마다 설정 다르게 가져갈 수 있음&lt;/li&gt;
&lt;li data-end=&quot;595&quot; data-start=&quot;552&quot;&gt;&lt;b&gt;커넥션 풀 관리&lt;/b&gt;: DB 커넥션을 효율적으로 재사용 &amp;rarr; 성능 향상&lt;/li&gt;
&lt;li data-end=&quot;643&quot; data-start=&quot;596&quot;&gt;&lt;b&gt;트랜잭션 제어&lt;/b&gt;: DB 세션을 명확히 제어 가능 &amp;rarr; 불필요한 세션 낭비 방지&lt;/li&gt;
&lt;/ul&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;style6&quot; /&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;span style=&quot;color: #409d00;&quot;&gt;&lt;b&gt; ✅&amp;nbsp; &lt;span style=&quot;color: #000000;&quot;&gt;server.xml (Tomcat) &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1745055650371&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;Resource
 name=&quot;jdbc/myDB&quot;
 auth=&quot;Container&quot;
 type=&quot;javax.sql.DataSource&quot;
 factory=&quot;org.apache.tomcat.jdbc.pool.DataSourceFactory&quot;
 driverClassName=&quot;oracle.jdbc.OracleDriver&quot;
 url=&quot;jdbc:oracle:thin:@192.168.111.14:1555/EZBILL&quot;
 username=&quot;myuser&quot;
 password=&quot;mypassword&quot;
 maxActive=&quot;10&quot;
 maxIdle=&quot;5&quot;
 maxWait=&quot;5000&quot;
 removeAbandoned=&quot;true&quot;
 removeAbandonedTimeout=&quot;60&quot;
 logAbandoned=&quot;true&quot;
 validationQuery=&quot;select 1 from dual&quot;/&amp;gt;&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; ✅ context.xml &lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1745055716312&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;Context&amp;gt;
  &amp;lt;ResourceLink name=&quot;jdbc/myDB&quot; global=&quot;jdbc/myDB&quot; type=&quot;javax.sql.DataSource&quot;/&amp;gt;
&amp;lt;/Context&amp;gt;&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; ✅ Java 코드에서 사용&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1745055729823&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;Context ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup(&quot;java:comp/env/jdbc/myDB&quot;);
Connection conn = ds.getConnection();&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;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; 커넥션 풀 설정 요소&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;style15&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20.814%;&quot;&gt;&lt;b&gt;설정명&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 79.186%;&quot;&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20.814%;&quot;&gt;&lt;b&gt; maxActive &lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 79.186%;&quot;&gt;동시에 사용할 수 있는 최대 연결 수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20.814%;&quot;&gt;&lt;b&gt; maxIdle &lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 79.186%;&quot;&gt;대기 상태로 유지되는 최대 연결 수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20.814%;&quot;&gt;&lt;b&gt; removeAbandoned &lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 79.186%;&quot;&gt;일정 시간 동안 사용되지 않으면 커넥션 회수 여부&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 20.814%;&quot;&gt;&lt;b&gt; validationQuery &lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 79.186%;&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;p data-ke-size=&quot;size16&quot;&gt; &lt;b&gt; 커넥션 풀을 잘 설정하면&lt;/b&gt;&lt;br /&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;style6&quot; /&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;blockquote data-ke-style=&quot;style2&quot;&gt;  &lt;b&gt;JNDI&lt;/b&gt;는 &amp;ldquo;J&lt;b&gt;ava 애플리케이션이 DB에 연결할 때&lt;/b&gt;&amp;rdquo; 사용함&lt;br /&gt;단순히 데이터를 넣고 뽑는 게 아니라 &lt;b&gt;WAS 환경에서 안정적으로 커넥션을 관리&lt;/b&gt;하려는 목적이 큼&lt;/blockquote&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;440&quot; data-start=&quot;350&quot;&gt;&lt;b&gt;Java 애플리케이션에서 DB에 연결해야 할 때&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;440&quot; data-start=&quot;387&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;440&quot; data-start=&quot;387&quot;&gt;JDBC를 직접 쓰기보다 &lt;b&gt;톰캣/WAS에 미리 등록해두고 꺼내 쓰는 구조&lt;/b&gt;가 필요할 때&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;534&quot; data-start=&quot;442&quot;&gt;&lt;b&gt;운영환경과 개발환경 설정을 분리하고 싶을 때&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;534&quot; data-start=&quot;477&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;534&quot; data-start=&quot;477&quot;&gt;코드에 DB URL/ID/PW를 직접 넣는 게 아니라 &lt;b&gt;환경 설정 파일에서만 관리하고 싶을 때&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;627&quot; data-start=&quot;536&quot;&gt;&lt;b&gt;DB 커넥션 풀을 도입하고 싶을 때&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;627&quot; data-start=&quot;566&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;627&quot; data-start=&quot;566&quot;&gt;세션을 효율적으로 재사용하고 &lt;b&gt;TPS(초당 트랜잭션 수)&lt;/b&gt; 가 많은 시스템에서 성능을 높이고 싶을 때&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;729&quot; data-start=&quot;629&quot;&gt;&lt;b&gt;세션 누수 DB 접속 제한 같은 문제를 방지하고 싶을 때&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;729&quot; data-start=&quot;672&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;729&quot; data-start=&quot;672&quot;&gt;DB_LINK처럼 세션이 계속 유지되는 방식 대신 &lt;b&gt;명확하게 열고 닫히는 구조&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;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt; ❌ 꼭 JNDI를 안 써도 되는 경우&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;809&quot; data-start=&quot;762&quot;&gt;&lt;b&gt;아주 작은 테스트용 프로젝트&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;809&quot; data-start=&quot;786&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;809&quot; data-start=&quot;786&quot;&gt;DB 접속도 1~2회 트랜잭션도 적음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;866&quot; data-start=&quot;811&quot;&gt;&lt;b&gt;로컬에서만 쓰는 간단한 툴성 애플리케이션&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;866&quot; data-start=&quot;842&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;866&quot; data-start=&quot;842&quot;&gt;환경 분리나 커넥션 관리가 중요하지 않음&lt;/li&gt;
&lt;/ul&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-end=&quot;2007&quot; data-start=&quot;1997&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-end=&quot;2007&quot; data-start=&quot;1997&quot; 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;span style=&quot;color: #666666;&quot;&gt;JNDI는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;Java와 DB를 안정적으로 연결하고&lt;/b&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #666666;&quot;&gt;&lt;b&gt;DB 커넥션을 효율적으로 관리할 수 있게 해주는 설정 방식&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;&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;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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/JAVA</category>
      <category>datasource</category>
      <category>DB성능관리</category>
      <category>db연결</category>
      <category>java개발</category>
      <category>JNDI</category>
      <category>was환경</category>
      <category>백엔드개발</category>
      <category>웹개발</category>
      <category>커넥션풀</category>
      <category>톰캣설정</category>
      <author>리신</author>
      <guid isPermaLink="true">https://dev-cini.tistory.com/90</guid>
      <comments>https://dev-cini.tistory.com/90#entry90comment</comments>
      <pubDate>Sun, 20 Apr 2025 00:00:07 +0900</pubDate>
    </item>
    <item>
      <title>[Oracle] 오라클 디비링크(DB LINK)란?</title>
      <link>https://dev-cini.tistory.com/89</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2400&quot; data-origin-height=&quot;1600&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6mpYB/btsNrmh86KP/lAhqTlPHolcgNc75fWFSak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6mpYB/btsNrmh86KP/lAhqTlPHolcgNc75fWFSak/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6mpYB/btsNrmh86KP/lAhqTlPHolcgNc75fWFSak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6mpYB%2FbtsNrmh86KP%2FlAhqTlPHolcgNc75fWFSak%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;2400&quot; height=&quot;1600&quot; data-origin-width=&quot;2400&quot; data-origin-height=&quot;1600&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;오라클에서 외부 DB와 연결할 때 사용하는&lt;b&gt; &lt;span style=&quot;color: #ee2323;&quot;&gt;DB LINK&lt;/span&gt;&lt;/b&gt;는&lt;br /&gt;간편하지만 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;세션 부하 등 주의가 필요한 기능&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;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;DB LINK&lt;/b&gt;&lt;b&gt;란?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-end=&quot;335&quot; data-start=&quot;232&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;DB_LINK(Database Link)&lt;/b&gt;는 오라클 DB에서 &lt;b&gt;다른 원격 DB의 객체(테이블, 뷰 등)&lt;/b&gt;를&lt;br /&gt;&lt;b&gt;로컬 DB에서 직접 접근&lt;/b&gt;할 수 있도록 만들어주는 기능이다.&lt;/p&gt;
&lt;p data-end=&quot;335&quot; data-start=&quot;232&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;335&quot; data-start=&quot;232&quot; data-ke-size=&quot;size16&quot;&gt;운영&amp;nbsp;중&amp;nbsp;서로&amp;nbsp;다른&amp;nbsp;DB&amp;nbsp;인스턴스를&amp;nbsp;연결해야&amp;nbsp;할&amp;nbsp;상황이&amp;nbsp;생깁니다.&amp;nbsp;&amp;nbsp; &lt;br /&gt;&lt;span style=&quot;color: #009a87;&quot;&gt;&lt;b&gt;예를&amp;nbsp;들어&lt;/b&gt;&lt;/span&gt;&amp;nbsp;A&amp;nbsp;시스템에서&amp;nbsp;B&amp;nbsp;시스템의&amp;nbsp;테이블에&amp;nbsp;접근하거나&amp;nbsp;데이터를&amp;nbsp;쓰고&amp;nbsp;싶을&amp;nbsp;때&lt;/p&gt;
&lt;p data-end=&quot;400&quot; data-start=&quot;337&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;가장 간편한 방법&lt;/b&gt; 중 하나가 바로&lt;b&gt; DB LINK&lt;/b&gt;입니다.&lt;/p&gt;
&lt;p data-end=&quot;400&quot; data-start=&quot;337&quot; 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;b&gt; ✅ SELECT 예시 &lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1745045046191&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;SELECT * FROM customer@ERP_LINK;&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;✅ INSERT 예시 &lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1745048583453&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;INSERT INTO log_table@LOG_DB_LINK (id, message) VALUES (1, '처리 완료');&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;✅ DB_LINK 생성 예시&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1745048596872&quot; class=&quot;sql&quot; data-ke-language=&quot;sql&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;CREATE DATABASE LINK LOG_DB_LINK
CONNECT TO log_user IDENTIFIED BY log_password
USING 'LOG_TNS_ENTRY';&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;&amp;nbsp;&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; DB LINK의 장점 &lt;/b&gt;&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100.695%;&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 style=&quot;width: 25.6977%;&quot;&gt;&lt;b&gt;항목&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 82.1764%;&quot;&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25.6977%;&quot;&gt;&lt;b&gt;간편한 연동&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 82.1764%;&quot;&gt;외부 DB에 복잡한 설정 없이 SQL만으로 접근 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25.6977%;&quot;&gt;&lt;b&gt;트랜잭션 공유 가능&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 82.1764%;&quot;&gt;로컬 트랜잭션과 외부 트랜잭션을 하나로 묶을 수 있음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25.6977%;&quot;&gt;&lt;b&gt;데이터 조회,사입 가능&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 82.1764%;&quot;&gt;SELECT뿐 아니라 INSERT/UPDATE등도 가능&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;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;DB LINK의 단점&lt;/b&gt;&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100.345%; height: 89px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 21px; background-color: #ee2323; color: white; font-weight: bold;&quot;&gt;
&lt;td style=&quot;width: 16.0466%; height: 21px;&quot;&gt;&lt;b&gt;항목&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 66.5673%; height: 21px;&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: 16.0466%; height: 17px; background-color: #f3f3f3;&quot;&gt;&lt;b&gt;트랜잭션 처리 복잡&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 66.5673%; height: 17px;&quot;&gt;외부 DB까지 트랜잭션이 퍼지면서 오류 시 Rollback 문제가 생길 수 있음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 16.0466%; height: 17px; background-color: #f3f3f3;&quot;&gt;&lt;b&gt;성능 이슈&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 66.5673%; height: 17px;&quot;&gt;외부 DB 응답 속도에 따라 전체 SQL이 느려질 수 있음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 16.0466%; height: 17px; background-color: #f3f3f3;&quot;&gt;&lt;b&gt;세션 누수&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 66.5673%; height: 17px;&quot;&gt;사용 후 세션이 INACTIVE 상태로 남는 롱 아이들 세션이 발생할 수 있음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 16.0466%; height: 17px; background-color: #f3f3f3;&quot;&gt;&lt;b&gt;장애 시 리스크&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 66.5673%; height: 17px;&quot;&gt;외부 DB 연결 문제로 우리 시스템까지 영향을 받을 수 있음&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;
&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;   DB LINK는 언제 왜 써야 할까?&lt;/b&gt;&lt;/h3&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;&amp;rarr; DB LINK는 아래와 같은 상황에서 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;간단하고 강력한 선택지&lt;/b&gt;&lt;/span&gt;가 된다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;349&quot; data-start=&quot;226&quot;&gt;&lt;b&gt;빠르게 다른 DB와 연동해야 할 때&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;349&quot; data-start=&quot;256&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;307&quot; data-start=&quot;256&quot;&gt;예: 내부 시스템이 2개 DB로 나뉘어 있는데 데이터를 조인하거나 비교해야 할 경우&lt;/li&gt;
&lt;li data-end=&quot;349&quot; data-start=&quot;311&quot;&gt;JNDI 설정까지 시간이 없거나 단기간 데이터 조회만 필요할 때&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;466&quot; data-start=&quot;351&quot;&gt;&lt;b&gt;운영 중인 타 시스템 DB에 직접 접근해야 할 때&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;466&quot; data-start=&quot;389&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;430&quot; data-start=&quot;389&quot;&gt;다른 팀에서 운영하는 DB를 우리 쿼리에서 직접 조회해야 하는 경우&lt;/li&gt;
&lt;li data-end=&quot;466&quot; data-start=&quot;434&quot;&gt;REST API 또는 별도 연계 없이 빠르게 활용 가능&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;583&quot; data-start=&quot;468&quot;&gt;&lt;b&gt;트랜잭션 공유가 필요한 경우&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;583&quot; data-start=&quot;494&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;534&quot; data-start=&quot;494&quot;&gt;우리 DB와 외부 DB 모두 한 트랜잭션 내에서 처리되어야 할 때&lt;/li&gt;
&lt;li data-end=&quot;583&quot; data-start=&quot;538&quot;&gt;예: insert(우리DB) &amp;rarr; insert@link(외부DB) &amp;rarr; commit 같이 일괄 처리&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; &lt;/b&gt;&lt;b&gt;언제 쓰면 안 되는가?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반대로 아래 상황이라면 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;JNDI, API, 메시징 방식&lt;/b&gt;&lt;/span&gt;이 더 적합함&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;187&quot; data-start=&quot;114&quot;&gt;&lt;b&gt;TPS(초당 처리량)가 높은 시스템이라면&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;187&quot; data-start=&quot;114&quot;&gt;DB LINK는 세션 관리가 어려워지고 &lt;b&gt;병목이 발생할 가능성이 높음&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;276&quot; data-start=&quot;189&quot;&gt;&lt;b&gt;외부 DB의 장애가 곧 우리 시스템에도 영향을 줄 수 있는 구조라면&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;276&quot; data-start=&quot;189&quot;&gt;DB LINK는 그 &lt;b&gt;장애를 그대로 전파&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;373&quot; data-start=&quot;278&quot;&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 data-end=&quot;373&quot; data-start=&quot;278&quot;&gt;DB LINK는 연결 구조가 불투명하고 &lt;b&gt;관리 포인트가 늘어&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;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-end=&quot;859&quot; data-start=&quot;850&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;  결론&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;915&quot; data-start=&quot;861&quot; data-ke-size=&quot;size16&quot;&gt;DB_LINK는 &lt;b&gt;편리함과 유연함&lt;/b&gt;을 제공하지만 그만큼 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;리스크도 존재함&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;998&quot; data-start=&quot;917&quot; data-ke-size=&quot;size16&quot;&gt;따라서 아래처럼 &lt;b&gt;&amp;ldquo;간단한 연동&amp;rdquo;&lt;/b&gt;, &lt;b&gt;&amp;ldquo;일시적인 조회&amp;rdquo;&lt;/b&gt;, &amp;ldquo;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;트랜잭션 동기 처리가 꼭 필요한 경우&lt;/b&gt;&lt;/span&gt;&amp;rdquo;에만 사용하는 것이 이상적임&lt;/p&gt;
&lt;blockquote data-end=&quot;1059&quot; data-start=&quot;1000&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;1059&quot; data-start=&quot;1002&quot; data-ke-size=&quot;size16&quot;&gt;✔️ 작고 단순한 연동에는 효율적&lt;br /&gt;❌ 복잡하거나 고부하 시스템엔 신중히 검토할 것&lt;/p&gt;
&lt;/blockquote&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;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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DataBase/Oracle</category>
      <category>DatabaseLink</category>
      <category>DBLink</category>
      <category>DB성능</category>
      <category>JNDI</category>
      <category>데이터베이스연동</category>
      <category>디비링크</category>
      <category>세션이슈</category>
      <category>오라클db</category>
      <category>오라클디비링크</category>
      <category>트랜잭션관리</category>
      <author>리신</author>
      <guid isPermaLink="true">https://dev-cini.tistory.com/89</guid>
      <comments>https://dev-cini.tistory.com/89#entry89comment</comments>
      <pubDate>Sat, 19 Apr 2025 18:02:32 +0900</pubDate>
    </item>
    <item>
      <title>[ JAVA ] 네트워킹 (Networking)</title>
      <link>https://dev-cini.tistory.com/88</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;네트워킹&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;&lt;b&gt;네트워킹이란 두 대 이상의 컴퓨터를 케이블로 연결하여 네트워크를 구성하는 것을 말한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;&lt;b&gt;네트워킹의 개념은 컴퓨터들을 서로 연결하여 데이터를 손쉽게 주고받거나 또는 자원프린터와 같은 주변기기를 함께 공유하고자 하는 노력에서 시작되었다.&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;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;&quot;&gt;&lt;b&gt;자바에서 제공하는 &lt;span style=&quot;text-align: start;&quot;&gt;java.net패키지를 사용해 네트워크 어플리케이션의 데이터 통신 부분을 쉽게 작성할 수 있으며,&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;&quot;&gt;&lt;b&gt;&lt;span style=&quot;text-align: start;&quot;&gt;간단한 네트워크 어플리케이션은 단 몇 줄의 자바코드 만으로도 작성이 가능하다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&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;style6&quot; /&gt;
&lt;h4 style=&quot;color: #666666; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;클라이언트/서버&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;클라이언트/서버는 컴퓨터간의 관계를 역할로 구분하는 개념이다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;서버 :&amp;nbsp; 서비스를 제공하는 컴퓨터&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;클라이언트 : 서비스를 사용하는 컴퓨터&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;서비스는 서버가 클라이언트로부터 요청받은 작업을 처리하여 그 결과를 제공하는 것을 뜻한다.&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;서버가 제공하는 서비스의 종류에 따라 파일서버, 메일서버, 어플리케이션 서버 등이 있다.&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;예를 들어, 파일서버는 클라이언트가 요청한 파일을 제공하는 서비스를 수행한다.&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;서버에 접속하는 클라이언트의 수에 따라 하나의 서버가 여러 가지 서비스를 제공하기도 하고&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt; 하나의 서비스를 여러 대의 서버로 제공하기도한다.&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;서버가 서비스를제공하기위해서는서버프로그램이있어야하고클라이언트가서비스를 제공받기ㅔ 위해서는 서버프로그램과 연결할 수 있는 클라이언트 프로그램이 있어야 한다.&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;예를들면, 웹서버에 접속하여 정보를 얻기 위해서는 웹브라우저가 있어야 하고, FTP서버에 접속해서 파일을 전송받기&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;위해서는 알FTP와 같은 FTP클라이언트 프로그램이 필요하다.&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;네트워크를 구성할 때 전용서버를 두는 것을 서버기반모델(server-based model)이라 하고 별도의 전용서버없이 각 클라이언트가 서버열할을 동시에 수행하는 것을 P2P모텔(peer-to-peer)이라 한다.&lt;/b&gt;&lt;/span&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%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;서버기반모델(server-based model)&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;P2P모텔(peer-to-peer)&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;- 안정적인 서비스의 제공이 가능하다.&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;- 공유 데이터의 관리와 보안이 용이하다&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;- 서버구축비용과 관리비용이 든다.&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;- 서버구축 및 운용비용을 절감할 수 있다.&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;- 자원의 활용을 극대화 할 수 있다.&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;-&amp;nbsp; 자원의 관리가 어렵다.&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;- 보안이 취약하다.&lt;/span&gt;&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;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;IP 주소 (IP address)&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;IP주소는 컴퓨터(호스트, host)를 구별하는데 상뇽되는 고유한 값으로 인터넷에 연결된 모든 컴퓨터는 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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;IP주소는 네트워크 주소와 호스트 주소로 나눌 수 있는데, 32bit(4byte)의 IP주소 중에서 네트워크주소와 호스트주소가 각각 몇&amp;nbsp; bit를 차지하는 지는 네트워크를 어떻게 구성하였는지에 따라 달라진다.&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;그리고 서로 다른 두 호스트의 IP주소의 네트워크 주소가 같다는 것은 두 호스트가 같은 네트워크에 포한되어 있다는 것을 의미한다.&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;InetAddress&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;자바에서는 IP주소를 다루기 위한 클래스로 InetAddress를 제공한다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;아래 링크에서 메소드들을 확인 할 수 있다.&lt;/span&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;b&gt;&lt;a href=&quot;https://docs.oracle.com/javase/7/docs/api/java/net/InetAddress.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://docs.oracle.com/javase/7/docs/api/java/net/InetAddress.html&lt;/a&gt;&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1682433895635&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;InetAddress (Java Platform SE 7 )&quot; data-og-description=&quot;Gets the fully qualified domain name for this IP address. Best effort method, meaning we may not be able to return the FQDN depending on the underlying system configuration. If there is a security manager, this method first calls its checkConnect method wi&quot; data-og-host=&quot;docs.oracle.com&quot; data-og-source-url=&quot;https://docs.oracle.com/javase/7/docs/api/java/net/InetAddress.html&quot; data-og-url=&quot;https://docs.oracle.com/javase/7/docs/api/java/net/InetAddress.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://docs.oracle.com/javase/7/docs/api/java/net/InetAddress.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://docs.oracle.com/javase/7/docs/api/java/net/InetAddress.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;InetAddress (Java Platform SE 7 )&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Gets the fully qualified domain name for this IP address. Best effort method, meaning we may not be able to return the FQDN depending on the underlying system configuration. If there is a security manager, this method first calls its checkConnect method wi&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;docs.oracle.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;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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;URL&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #666666; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;인터넷에 존재하는 여러 서버들이 제공하는 자원에 접근할 수 있는 주소를 표현하기 위한 것이다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #666666; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;'프로토콜://호스트명:포트번호/경로명/파일명?쿼리스트링#참조' 의 형태로 이루어져 있다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;&lt;b&gt;http://www.codechobo.com:80/sample/hello.html?referer=codechobo#index1&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;&lt;b&gt;프로토콜 자원에 접근하기 위해 서버와 통신하는데 사용되는 통신규약 (&lt;span style=&quot;color: #0593d3;&quot;&gt;http&lt;/span&gt;) &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;&lt;b&gt;호스트명 자원을 제공하는 서버의 이름 (&lt;span style=&quot;color: #0593d3;&quot;&gt;www.javachobo.com&lt;/span&gt;) &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;&lt;b&gt;포트번호 통신에 사용되는 서버의 포트번호 (&lt;span style=&quot;color: #0593d3;&quot;&gt;80&lt;/span&gt;) &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;&lt;b&gt;경로명 접근하려는 자원이 저장된 서버상의 위치 (&lt;span style=&quot;color: #0593d3;&quot;&gt;/sample&lt;/span&gt;) &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;&lt;b&gt;파일명 접근하려는 자원의 이름 (&lt;span style=&quot;color: #0593d3;&quot;&gt;hello.html&lt;/span&gt;) &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;&lt;b&gt;쿼리(query) URL에서'?' 이후의 부분 (&lt;span style=&quot;color: #0593d3;&quot;&gt;referer=javachobo&lt;/span&gt;) &lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;&lt;b&gt;참조(anchor) URL에서 '#' 이후의 부분 (&lt;span style=&quot;color: #0593d3;&quot;&gt;index1&lt;/span&gt;)&lt;/b&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;URLConnection&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #333333;&quot;&gt;&lt;b&gt;&lt;span style=&quot;text-align: start;&quot;&gt;어플리케이션과 URL간의 통신연결을 나타내는 클래스의 최상위 클래스, 추상클래스이다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;URLConnection을 상속받아 구현한 클래스로는 HttpURLConnection과 JarURLConnection이 있으며,&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;URL의 프로토콜이 http프로토콜이라면 openConnection()은 Http URLConnection을 반환한다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;참고자료 : 자바의 정석&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>프로그래밍/JAVA</category>
      <category>java</category>
      <category>네트워킹</category>
      <category>자바</category>
      <category>자바의 정석</category>
      <author>리신</author>
      <guid isPermaLink="true">https://dev-cini.tistory.com/88</guid>
      <comments>https://dev-cini.tistory.com/88#entry88comment</comments>
      <pubDate>Tue, 25 Apr 2023 23:55:52 +0900</pubDate>
    </item>
    <item>
      <title>[ JAVA ] 직렬화란</title>
      <link>https://dev-cini.tistory.com/87</link>
      <description>&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #292929; text-align: start;&quot;&gt;객체를 저장하거나 메모리, 데이터베이스 혹은 파일로 옮기려면 어떻게 해야할까?&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #292929; text-align: start;&quot;&gt;이럴 때 필요한 것이 &lt;span style=&quot;color: #ee2323;&quot;&gt;직렬화다.&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #ee2323; text-align: start;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 id=&quot;직렬화&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;직렬화란?&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;직렬화란 객체를 데이터 스트림으로 만드는 것을 뜻한다. &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;즉 객체에 저장된 데이터를 스트림에 쓰기위해 연속적인 데이터로 변환하는 작업을 말한다. &lt;/span&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;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;솔직히 이렇게 말하면 어려운것 같다..&lt;/span&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;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;쉽게 말하면, 직렬화란 현재 데이터의 상태를 영속적으로 저장하거나 &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;다른 환경으로 전달(네트워크 통신 등)하기 위해 어떠한 정해진 포맷으로 변환하는 과정을 말한다.&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;그리고 이 변환된 데이터를 다시 원래 데이터로 변환 가능하며, 이러한 과정을 역직렬화라고 한다.&lt;/span&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;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;그리고 자바에서는 직렬화란?&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;자바 시스템 내부에서 사용되는 객체 또는 데이터를 외부의 자바 시스템에서도 사용할 수 있도록 바이트(byte) 형태로 데이터 변환하는 기술과 바이트로 변환된 데이터를 다시 객체로 변환하는 기술(역직렬화)을 아울러서 말한다.&lt;/span&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;시스템 적으로는 JVM(Java Virtual Machine)의 메모리에 상주(heap 또는 stack) 되어 있는 객체 데이터를 바이트 형태로 변환하는 기술과 직렬화된 바이트 형태의 데이터를 객체로 변환해서 JVM으로 상주시키는 형태를 말한다.&lt;/b&gt;&lt;/span&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;style6&quot; /&gt;
&lt;h4 id=&quot;objectinputstream-objectoutputstream&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;ObjectInputStream, ObjectOutputStream&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;직렬화에는 ObjectOutputStream을 사용하고, 역직렬화에는 ObjectInputStream을 사용한다. &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;각각은 OutputStream과 InputStream을 직접 상속받지만 기반스트림을 필요로 하는 보조 스트림이므로 객체 생성시 입출력할 스트림을 지정해주어야 한다.&lt;/span&gt;&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #006dd7;&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; text-align: start;&quot;&gt;예시)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #006dd7;&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; text-align: start;&quot;&gt;만약 파일에 객체를 저장(직렬화)하고 싶다면 아래와 같이 하면된다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1682431120794&quot; class=&quot;java&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;FileOutputStream fos = new FileOutputStream(&quot;objectfile.ser&quot;);
ObjectOutStream out = new ObjectOutStream(fos);

out.writeObject(new UserInfo());&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;위 코드는 objectfile.ser 이라는 파일에 UserInfo 객체를 직렬화 하여 저장한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;출력할 스트림(FileOutpu tStream)을 생성해서 이를 기반스트림으로 하는 ObjectOutputStream을 생성한다&lt;/b&gt;&lt;/span&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;ObjectOutStream의 writeObject(Object obj)를 사용해서 객체를 출력하면,&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;객체가 파일에 직렬화되어 저장된다.&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;역직렬화 방법도 간단하다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;직렬화할 때와는 달리 입력스트림을 사용하고 writeObject(Object obj)대신 readObject()를 사용하여 저장된 데이터를&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;읽기만 하면 객체로 역직렬화 된다.&lt;/b&gt;&lt;/span&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 id=&quot;직렬화-가능한-클래스-만들기---serializable-transient&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;직렬화 가능한 클래스 만들기 - Serializable, transient&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;직렬화하고자하는 클래스가 java.io.Serializable인터페이스를 구현하도록 하면 직렬화가 가능한 클래스를 만들 수 있다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt; 조상이 Serializable인터페이스를 구현하였다면 자손 클래스도 직렬화가 가능하다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1682431943467&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class UserInfo implements Serializable{
    Object obj = new Object(); // 직렬화 불가능
    Object obj = new String(&quot;abc&quot;); // 직렬화 가능
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;Object 객체는 직렬화할 수 없지만, 실제로 저장된 객체가 직렬화가 가능하다면 직렬화를 수행할 수 있다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 id=&quot;3-3-제어자-transient로-직렬화-대상에서-제외시키기&quot; style=&quot;color: #303030; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;transient&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p style=&quot;color: #303030; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;직렬화하고자 하는 객체의 클래스에 직렬화가 안 되는 객체에 대한 참조를 포함하고 있다면, &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #303030; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;제어자 transient를 붙여서 직렬화 대상에서 제외할 수 있다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1682432305152&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class UserInfo implements Serializable {
  String name;
  transient String password;  // 직렬화 대상에서 제외
  int age;
  transient Object obj = new Object();  // 직렬화 대상에서 제외&lt;/code&gt;&lt;/pre&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;style6&quot; /&gt;
&lt;h3 id=&quot;직렬화가능한-클래스의-버전관리&quot; style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;직렬화가능한 클래스의 버전관리&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;직렬화된 객체를 역직렬화할 때는 직렬화 했을 때와 같은 클래스를 사용해야한다. &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;그러나 클래스의 이름이 같더라도 내용이 변경된 경우에는 역직렬화에 실패하기 때문에 버전을 일치시켜야 한다. &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;객체를 직렬활 할 때 serialVersionUID라는 클래스 버전을 자동생성해서 직렬화 내용에 포함한 뒤,&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt; 역직렬화 할 때 클래스의 버전을 비교할 수 있게 한다.&lt;/span&gt;&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;그러나 static변수나 상수 또는 transient가 붙은 인스턴스변수가 추가되는 경우에는 직렬화에 영향을 미치지 않기 때문에 &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;클래스의 버전을 다르게 인식하도록 할 필요는 없다.&lt;/span&gt;&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;&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;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;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;참고자료 : 자바의 정석, 우아한형제들 기술블로그&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #212529; text-align: start;&quot;&gt;&lt;a href=&quot;https://techblog.woowahan.com/2550/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://techblog.woowahan.com/2550/&lt;/a&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1682431916527&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;{{item.name}} 자바의 직렬화 기술에 대한 대한 이야기입니다. 간단한 질문과 답변 형태로 자바 직렬화에 대한 간단한 설명과 직접 프로젝트를 진행하면서 겪은 경험에 대해 이야기해보려 합니다. &quot; data-og-host=&quot;techblog.woowahan.com&quot; data-og-source-url=&quot;https://techblog.woowahan.com/2550/&quot; data-og-url=&quot;https://techblog.woowahan.com/2550/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/hmT1B/hySpGtleR7/AAQXTouP0MWmmEuf7hYuj1/img.jpg?width=1640&amp;amp;height=856&amp;amp;face=0_0_1640_856,https://scrap.kakaocdn.net/dn/bA5Eds/hySpLnSJTW/nKKAhMKiVxDoMk7HkKkECk/img.jpg?width=1640&amp;amp;height=856&amp;amp;face=0_0_1640_856,https://scrap.kakaocdn.net/dn/b5sMX1/hySoEcQpfh/xqculHVVgYXj6xCDe8aJ5K/img.jpg?width=609&amp;amp;height=281&amp;amp;face=0_0_609_281&quot;&gt;&lt;a href=&quot;https://techblog.woowahan.com/2550/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://techblog.woowahan.com/2550/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/hmT1B/hySpGtleR7/AAQXTouP0MWmmEuf7hYuj1/img.jpg?width=1640&amp;amp;height=856&amp;amp;face=0_0_1640_856,https://scrap.kakaocdn.net/dn/bA5Eds/hySpLnSJTW/nKKAhMKiVxDoMk7HkKkECk/img.jpg?width=1640&amp;amp;height=856&amp;amp;face=0_0_1640_856,https://scrap.kakaocdn.net/dn/b5sMX1/hySoEcQpfh/xqculHVVgYXj6xCDe8aJ5K/img.jpg?width=609&amp;amp;height=281&amp;amp;face=0_0_609_281');&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;{{item.name}} 자바의 직렬화 기술에 대한 대한 이야기입니다. 간단한 질문과 답변 형태로 자바 직렬화에 대한 간단한 설명과 직접 프로젝트를 진행하면서 겪은 경험에 대해 이야기해보려 합니다.&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로그래밍/JAVA</category>
      <category>java</category>
      <category>역직렬화</category>
      <category>자바</category>
      <category>자바의 직렬화</category>
      <category>자바의정석</category>
      <category>직렬화</category>
      <author>리신</author>
      <guid isPermaLink="true">https://dev-cini.tistory.com/87</guid>
      <comments>https://dev-cini.tistory.com/87#entry87comment</comments>
      <pubDate>Tue, 25 Apr 2023 23:19:07 +0900</pubDate>
    </item>
    <item>
      <title>[ JAVA ] 입출력</title>
      <link>https://dev-cini.tistory.com/86</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;입출력이란?&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;I/O란 INPUT과 OUTPUT의 약자로 입력과 출력, 간단히 줄여서 입출력이라고 한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;입출력은 컴퓨터 내부 또는 외부의 장치와 프로그램간의 데이터를 주고받는 것을 말한다.&lt;/b&gt;&lt;/span&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;1. 스트림 (Stream)&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;한마디로 정의 하면 스트림이란 데이터를 운반하는데 사용되는 연결통로이다.&lt;/span&gt;&lt;/b&gt;&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;스트림의 특징&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;스트림은 단방향통신만&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;가능하다. &lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;따라서 입력과 출력을 동시에 처리 할 수 없다.&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;/span&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;size18&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;입력과 출력을 동시에 수행하려면❕❓&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;입력을 위한 입력스트림과 출력을 위한 출력스트림,&amp;nbsp; 2개의 스트림이 필요하다.&lt;/span&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;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;그리고 스트림은 먼저 보낸 데이터를 먼저 받게 되어 있으며 중간에 건너뜀 없이 연속적으로 데이터를 주고받는다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;큐와 같은 FIFO(First In First Out)구조로 되어 있다고 생각하면 이해가 쉽다.&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;/span&gt;&lt;/b&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;2. 바이크기반 스트림 - InputStream, OutputStream&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;스트림은 바이트단위로 데이터를 전송하며 입출력 대상에 따라 아래의 표와 같이 입출력스트림이 있다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 110px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;입력스트림&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;출력스트림&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;입출력 대상의 종류&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;FileInputStream&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;FileOutputStream&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;파일&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;ByteArrayInputStream&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;ByteArrayOutputStream&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;메모리(byte배열)&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;PipedInputStream&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;PipedOutputStream&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;프로세스(프로세스간의 통신)&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;AudioInputStream&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;AudioOutputStream&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; height: 22px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;오디오장치&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;자바에서는 java.io패키지를 통해서 많은 종류의 입출력관련 클래스들을 제공하고 있으며,&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;입출력의 대상이 달라져도 동일한 방법으로 입출력이 가능하기 때문에 프로그래밍을 하기에 편리하다.&lt;/b&gt;&lt;/span&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%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;InputStream&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;OutputStream&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;abstract int read( )&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;abstract void write(int b)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;int read(byte[] b)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;void write(byte[] b)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;int read(byte[] b, int off, int len)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;void write(byte[] b, int off, int len)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;위 표에 나온 메서드의 사용법만 잘 알고 있어도 데이터를 읽고 쓰는 것은 입출력 대상의 종류에 관계없이 간단한 일이라고 한다.&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;InputStream의 read()와 OutputStream의 write(int b)는 입출력의 대상에 따라 읽고 쓰는 방법이 다를 것이기 때문에 &lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;각 상황에 알맞게 구현하라는 의미에서 추상메서드로 정의되어있다.&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;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;3. 보조 스트림&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;보조 스트림은 말그대로 스트림을 보조하는 역할을 한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;보조 스트림은 실제로 데이터를 주고받는 스트림이 아니기 때문에 데이터를 입출력 할 수 있는 기능은 없지만,&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;스트림의 기능을 향상시키거나 새로운 기능을 추가 할 수 있게 해준다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;예)&lt;/span&gt; test.txt라는 파일을 읽기 위해&amp;nbsp; FileInputStream을 사용할 때, 입력 성능을 향상시키기 위해 버퍼를 사용하는&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;보조스트림인 BuffereadInputStream을 사용한다.&lt;/b&gt;&lt;/span&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: 241px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 24.2635%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;입력&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25.3101%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;출력&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50.4263%; height: 20px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 24.2635%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;FilterInputStream&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25.3101%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;FilterOutputStream&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50.4263%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;필터를 이용한 입출력 처리&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 24.2635%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;BufferedInputStream&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25.3101%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;BufferedOutputStream&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50.4263%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;버퍼를 이용한 입출력 성능향상&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 40px;&quot;&gt;
&lt;td style=&quot;width: 24.2635%; height: 40px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;DataInputStream&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25.3101%; height: 40px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;DataOutputStream&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50.4263%; height: 40px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;int, float와 같은 기본형 단위로 데이터를 처리&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 24.2635%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;SequenceInputStream&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25.3101%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;없음&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50.4263%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;두 개의 스트림을 하나로 연결&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;width: 24.2635%; height: 21px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;LineNumberInputStream&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25.3101%; height: 21px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;없음&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50.4263%; height: 21px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;읽어 온 데이터의 라인 번호를 카운트&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 24.2635%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;ObjectInputStream&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25.3101%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;ObjectOutputStream&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50.4263%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;데이터를 객체단위로 읽고 쓰는데 사용&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 40px;&quot;&gt;
&lt;td style=&quot;width: 24.2635%; height: 40px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;없음&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25.3101%; height: 40px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;PrintStream&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50.4263%; height: 40px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;버퍼를 이용하여 추가적인 print관련 기능&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 40px;&quot;&gt;
&lt;td style=&quot;width: 24.2635%; height: 40px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;PushbackInputStream&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25.3101%; height: 40px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;없음&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50.4263%; height: 40px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;버퍼를 이용해서 읽어 온 데이터를 다시 되돌리는 기능&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;4. 문자기반 스트림 - Reader, Writer&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;Java에서는 한 문자를 의미하는 char형이 1byte가 아니라 2bute이기 때문에 바이트기반의 스트림으로 2byte인 문자를 처리하는 데는 어려움이 있다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;이 점을 보완하기 위해서 문자기반의 스트림이 제공된다.&lt;/b&gt;&lt;/span&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;table style=&quot;border-collapse: collapse; width: 100%; height: 198px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 22px;&quot;&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 22px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;바이트기반 스트림&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 22px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;문자기반 스트림&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 44px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 44px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;File&lt;/span&gt;InputStream&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;File&lt;/span&gt;OutputStream&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 44px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;File&lt;/span&gt;Reader&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;File&lt;/span&gt;Writer&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 44px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 44px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;ByteArray&lt;/span&gt;InputStream&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;ByteArray&lt;/span&gt;OutputStream&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 44px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;CharArray&lt;/span&gt;Reader&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;CharArray&lt;/span&gt;Writer&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 44px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 44px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;Piped&lt;/span&gt;InputStream&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;Piped&lt;/span&gt;OutputStream&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 44px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;Piped&lt;/span&gt;Reader&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;Piped&lt;/span&gt;Writer&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 44px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 44px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;StringBuffered&lt;/span&gt;InputStream&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: center;&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;span style=&quot;text-align: center;&quot;&gt;String&lt;/span&gt;Buffered&lt;/span&gt;OutputStream&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 44px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;String&lt;/span&gt;Reader&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;String&lt;/span&gt;Writer&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;문자기반 스트림의 이름은 바이트기반 스트림의 이름에서 뒤에 부분만 바꿔주면 된다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;InputStream&amp;nbsp; &amp;rarr; Reader&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;OutputStream &amp;rarr;&lt;/span&gt; Writer&lt;/b&gt;&lt;/blockquote&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;5. 바이트기반 스트림&lt;/span&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;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;InputStream 메서드&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #ffffff; color: #24292f; text-align: start; border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; width=&quot;784&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;background-color: #ffffff;&quot;&gt;
&lt;td style=&quot;background-color: #d9e5ff; color: #666666;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;메서드 명&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #d9e5ff; color: #666666;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;설 명&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;background-color: #f6f8fa;&quot;&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;int available()&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;스트림으로부터 읽어 올 수 있는 데이터의 크기를 반환한다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;background-color: #ffffff;&quot;&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;void close()&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;스트림을 닫음으로써 사용하고 있던 자원을 반환한다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;background-color: #f6f8fa;&quot;&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;void mark(int readlimit)&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;현재 위치를 표시해 놓는다. 후에 reset()에 의해서 표시해 놓은 위치로 다시 돌아갈 수 있다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;readlimit: 되돌아갈 수 있는 byte의 수&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;background-color: #ffffff;&quot;&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;boolean markSupported()&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;mark()와 reset()을 지원하는 지를 알려 준다.&amp;nbsp;이 메서드로 먼저 확인을 해야한다.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;background-color: #f6f8fa;&quot;&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;abstract int read()&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;1 byte를 읽어온다. 더 이상 읽을 데이터가 없다면 -1을 반환한다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;background-color: #ffffff;&quot;&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;int read(byte[] b)&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;배열 b의 크기만큼 읽어서 배열을 채우고 읽어 온 데이터의 수를 반환한다.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;background-color: #f6f8fa;&quot;&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;int read(byte[] b, int off, int len)&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;최대 len 개의 byte를 읽어서 배열 b의 위치off부터 저장한다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;background-color: #ffffff;&quot;&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;void reset()&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;스트림에서 위치를 마지막으로 mark()이 호출되었던 위치로 되돌린다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;background-color: #f6f8fa;&quot;&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;long skip(long n)&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;스트림에서 주어진 길이n만큼 건너뛴다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;OutputStream 메서드&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #ffffff; color: #24292f; text-align: start; border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; width=&quot;784&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;background-color: #ffffff;&quot;&gt;
&lt;td style=&quot;background-color: #d9e5ff; color: #666666;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;메서드 명&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;background-color: #d9e5ff; color: #666666;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;설 명&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;background-color: #f6f8fa;&quot;&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;void close()&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;입력소스를 닫음으로써 사용하고 있던 자원을 반환한다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;background-color: #ffffff;&quot;&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;void flush()&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;스트림의 버퍼에 있는 모든 내용을 출력소스에 쓴다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;background-color: #f6f8fa;&quot;&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;abstract void write(int b)&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;주어진 값을 출력소스에 쓴다.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;background-color: #ffffff;&quot;&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;void write(byte[] b)&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;주어진 배열 b에 저장된 모든 내용을 출력소스에 쓴다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;background-color: #f6f8fa;&quot;&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;void write(byte[] b, int off, int len)&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;color: #666666;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;주어진 배열 b에 저장된 내용 중에서 off번째 부터 len개 만큼만을 읽어서 출력소스에 쓴다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&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;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;스트림의 종류에 따라서 mark()와 reset()을 사용하여 이미 읽은 데이터를 되돌려서 다시 읽을 수 있다. &lt;br /&gt;이 기능을 지원하는 스트림인지 확인하는&amp;nbsp; markSupported()를 통해서 알 수 있다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt; &lt;br /&gt;flush()는 버퍼가 있는 출력스트림의 경우에만 의미가 있으며, OutputSteream에 정의된 flush()는 아무런 일도 하지 않는다. &lt;br /&gt;프로그램이 종료될 때, 사용하고 닫지 않은 스트림을 JVM이 자동적으로 닫아 주기는 하지만,&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;스트림을 사용해서 모든 작업을 마치고 난 후에는 close()를 호출해서 반드시 닫아 주어야 한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;그러나&amp;nbsp;ByteArrayInputStream과&amp;nbsp;같이&amp;nbsp;메모리를&amp;nbsp;사용하는&amp;nbsp;스트림과 &lt;br /&gt;System.in,&amp;nbsp;System.out과&amp;nbsp;같은&amp;nbsp;표준&amp;nbsp;입출력&amp;nbsp;스트림은&amp;nbsp;닫아&amp;nbsp;주지&amp;nbsp;않아도&amp;nbsp;된다.&lt;/b&gt;&lt;/span&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;6. ByteArrayInputStream과 ByteArrayOutputStream&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;두 스트림은 메모리, 즉 바이트배열에 데이터를 입출력 하는데 사용되는 스트림이다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;주로 다른 곳에 입출력하기전에 데이터를 임시로 바이트배열에 담아서 변환 등의 작업을 하는데 사용된다.&lt;/span&gt;&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;예제를 보면 아래의 코드는 &lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;ByteArrayInputStream ByteArrayOutputStream을 이용해서 바이트배열 inSrc의 데이터를 outSrc로 복사하는 예제이다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1680619595836&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Main {
    public static void main(String[] args) {
        byte[] inSrc = {0,1,2,3,4,5,6,7,8,9};
        byte[] outSrc = null;

        ByteArrayInputStream input = null;
        ByteArrayOutputStream output = null;

        input = new ByteArrayInputStream(inSrc);
        output = new ByteArrayOutputStream();

        int data = 0;
        // read()를 호출한 반환값을 변수 data에 저장한 후 data에 저장된 값이 -1인지 비교
        while((data = input.read()) != -1) {
            output.write(data); 
        }

        outSrc = output.toByteArray(); // 스트림의 내용을 byte배열로 반환한다.

        System.out.println(&quot;Input Source: &quot; + Arrays.toString(inSrc));
        System.out.println(&quot;output Source: &quot; + Arrays.toString(outSrc));
    }
}

/*
  출력결과
  Input Source: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  output Source: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
*/&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;바이트배열은 사용하는 자원이 메모리 밖에 없으므로 가비지컬렉터에 의해 자동적으로 자원을 반환하므로 close()를 이용해서 스트림을 닫지 않아도 된다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #24292f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그리고 위 코드는 read()와 write( int b)만 사용하기 때문에 한번에 1 byte만 읽고 쓰므로 작업효율이 떨어진다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #24292f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #24292f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;그러면 효율적이게 작업을 하기 위해서는 어떻게 해야할까?&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #24292f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;아래의 예제를 보면 &lt;/b&gt;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;int read(byte[] b, int off, int len)와 void write(byte[] b, int off, int len)을 이용해서 입출력하는 방법을 보여주는 예이다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #24292f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #24292f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이전 예제와는 달리 byte배열을 이용해서 한 번에 배열의 크기만큼 읽고 쓸 수 있다.&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;background-color: #ffffff; color: #24292f; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;만약 스트림의 크기를 정확히 모를 때는 일정한 크기의 바이트를 계속해서 받아서 써야한다.&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1680621370591&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Main {
    public static void main(String[] args) {
        byte[] inSrc = {0,1,2,3,4,5,6,7,8,9};
        byte[] outSrc = null;

        byte[] temp = new byte[10];

        ByteArrayInputStream input = null;
        ByteArrayOutputStream output = null;

        input = new ByteArrayInputStream(inSrc);
        output = new ByteArrayOutputStream();

        input.read(temp, 0, temp.length);       // 읽어 온 데이터를 temp에 담는다.
        output.write(temp, 5, 5);           // temp[5]부터 5개의 데이터를 write한다.

        outSrc = output.toByteArray();

        System.out.println(&quot;Input Source: &quot; + Arrays.toString(inSrc));
        System.out.println(&quot;temp Source: &quot; + Arrays.toString(temp));
        System.out.println(&quot;output Source: &quot; + Arrays.toString(outSrc));

    }
}
/*
출력결과
Input Source: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
temp Source: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
output Source: [5, 6, 7, 8, 9]


*/&lt;/code&gt;&lt;/pre&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;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;7. FileInputStream과 &lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;FileOutputStream&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;FileInputStream/FileOutputStream은 파일에 입출력을 하기 위한 스트림이다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 155px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style3&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #1a5490;&quot;&gt;&lt;b&gt;생성자&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 20px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #1a5490;&quot;&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 16px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 16px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: left;&quot;&gt;FileInputStream(String filePath)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 16px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: left;&quot;&gt;filepath&lt;span style=&quot;color: #222222; text-align: left;&quot;&gt;로 지정한 파일에 대한 입력 스트림을 생성한다.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: left;&quot;&gt;FileInputStream(File fileObj)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: left;&quot;&gt;fileObj로 지정한 파일에 대한 입력 스트림을 생성한다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: left;&quot;&gt;FileInputStream(FileDescriptor fdObj)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: left;&quot;&gt;fdObj 로 기존의 접속을 나타내는 파일 시스템의 입력 스트림을 생성한다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: left;&quot;&gt;FileOutputStream(String filepath)&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: left;&quot;&gt;filepath로 지정한 파일에 대한 OutputStream을 생성한다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: left;&quot;&gt;FileOutputStream(String filepath)&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: left;&quot;&gt;지정한 파일로 OutputStream을 생성한다. append 인자로 출력할 때 append 모드를 설정한다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: left;&quot;&gt;FileOutputStream(File fileObj)&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: left;&quot;&gt;fileObj로 지정된 파일에 대한 OutputStream을 생성한다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: left;&quot;&gt;FileOutputStream(File fileObj, boolean append)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: left;&quot;&gt;fileObj로 지정된 파일에 대한 OutputStream을 생성한다. append 인자로 출력할 때 append 모드를 설정한다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: left;&quot;&gt;FileOutputStream(FileDescriptor fdObj)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #222222; text-align: left;&quot;&gt;fdObj 로 기존의 접속을 나타내는 파일 시스템의 OutputStream을 생성한다.&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;* 단순히 텍스트파일을 다루는 경우에는 문자기반의 스트림인 FileReader/FileWriter를 사용하는 것이 더 좋다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #ee2323;&quot;&gt;*참고 : JAVA의 정석&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;</description>
      <category>프로그래밍/JAVA</category>
      <category>InputStream</category>
      <category>outputstream</category>
      <category>입출력</category>
      <category>자바</category>
      <author>리신</author>
      <guid isPermaLink="true">https://dev-cini.tistory.com/86</guid>
      <comments>https://dev-cini.tistory.com/86#entry86comment</comments>
      <pubDate>Wed, 5 Apr 2023 00:57:58 +0900</pubDate>
    </item>
  </channel>
</rss>