μλ° κ°λ°μλΌλ©΄ νλ²μ―€μ λ€μ΄λ΄€κ³ , νλ²μ―€μ μ¬μ©νμλ²ν logger λ‘ log4jκ° μμκ²μ΄λ€. νμ§λ§ μ΅κ·Όλ€μ΄ logbackμ΄λΌλκ²μ μκ²λμκ³ , μ logbackμ μ¬μ©ν΄μΌ νλ μ΄μ λΌλ κΈμ΄ μμμ λλ‘ μ¬λ¬ μΈ‘λ©΄μμ κ°μ μ΄ λλ― νλ€. (λ§ν¬) μ΄λ²μ μμ±ν κΈμ λͺ©μ μ logbackμ μ€μ νκ³ μ΄λ»κ² μ¬μ©νλμ§μ λν΄ μμ±ν΄ λ³΄κ³ μ νλ€. ⻠곡μμ¬μ΄νΈ : https://logback.qos.ch/
pom.xml mavenꡬ쑰λΌκ³ κ°μ νμλ logback Dependencyλ₯Ό κ°μ Έμ€κΈ° μν΄μλ μλμ κ°μ΄ pom.xml μ μ€μ ν΄ μ£Όλ©΄ λλ€.
<dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.1.7</version> <!--λ²μ μ μν©μ λ°λΌ --> </dependency> λ‘κ·Έλ 벨 ERROR, WARN, INFO, DEBUG or TRACE
# logback μ€μ νμΌ μΌλ°μ μΌλ‘ logback.xml μ΄λΌλ μ΄λ¦μΌλ‘ λ§λ€μ΄ src/main/resources/μλμ μμΉνκ² λλ€. Spring-Boot νκ²½μμλ logback-spring.xml μ΄λΌλ μ΄λ¦μΌλ‘ μ€μ ν΄μΌ νλλ° logback.xmlλ‘ μ€μ νλ©΄ μ€νλ§λΆνΈκ° μ€μ νκΈ° μ μ λ‘κ·Έλ°± κ΄λ ¨ν μ€μ μ νκΈ° λλ¬Έμ μ μ΄ν μκ° μκ² λλ€. ( 곡μμ¬μ΄νΈ λ©λ΄μΌ : https://logback.qos.ch/documentation.html )
<?xml version="1.0" encoding="UTF-8"?> <configuration> <include resource="org/springframework/boot/logging/logback/defaults.xml" /> <include resource="org/springframework/boot/logging/logback/console-appender.xml" /> <!-- λ³μ μ§μ --> <property name="LOG_DIR" value="/logs" /> <property name="LOG_PATH_NAME" value="${LOG_DIR}/data.log" /> <!-- FILE Appender --> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_PATH_NAME}</file> <!-- μΌμλ³λ‘ λ‘κ·ΈνμΌ μ μ©νκΈ° --> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_PATH_NAME}.%d{yyyyMMdd}</fileNamePattern> <maxHistory>60</maxHistory> <!-- μΌμλ³ λ°±μ
νμΌμ 보κ΄κΈ°κ° --> </rollingPolicy> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss} [%-5p] [%F]%M\(%L\) : %m%n</pattern> </encoder> </appender> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <layout class="ch.qos.logback.classic.PatternLayout"> <pattern>%d{yyyy-MM-dd HH:mm:ss} [%-5p] [%F]%M\(%L\) : %m%n</pattern> </layout> </appender> <!-- TRACE > DEBUG > INFO > WARN > ERROR, λμλ¬Έμ κ΅¬λΆ μν¨ --> <!-- profile μ μ½μ΄μ appender μ μ€μ ν μ μλ€.(phaseλ³ νμΌμ μλ§λ€μ΄λ λλ μ’μ κΈ°λ₯) --> <springProfile name="local"> <root level="DEBUG"> <appender-ref ref="FILE" /> <appender-ref ref="STDOUT" /> </root> </springProfile> <springProfile name="real"> <root level="INFO"> <appender-ref ref="FILE" /> <appender-ref ref="STDOUT" /> </root> </springProfile> </configuration> java μ½λ©μμμ λ‘κΉ
μ€μ μ¬μ©μ λ€μκ³Ό κ°μ΄ LoggerFactoryλ₯Ό μ΄μ©ν΄μ μ¬μ©νκ±°λ Lombokμ΄λ
Έν
μ΄μ
μ νμ©νλ©΄ μ¬ννκ² μ¬μ©μ΄ κ°λ₯νλ€.
LoggerFactory μ¬μ© import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Foo { static final Logger logger = LoggerFactory.getLogger(Foo.class); public void test() { logger.debug("ID : {}", "foo"); } } Lombok μ΄λ
Έν
μ΄μ
μ¬μ© import lombok.extern.slf4j.Slf4j; @Slf4j public class Foo { public void test() { log.debug("ID : {}", "foo"); } } λ§μΉλ©° μΌλ°μ μΈ μΉ μ΄ν리μΌμ΄μ
μμλ WASμμ λ‘κΉ
μ λ°λ‘ κ΄λ¦¬νκ³ μκΈ° λλ¬Έμ file λ‘ λ‘κΉ
μ ν νμλ μμκ² κ°λ€.(μΌλ° jar ννμμλ νμΌ λ‘κΉ
μ΄ νμ ν μλ…)
μ°Έκ³ μ¬μ΄νΈ http://yookeun.github.io/java/2015/11/10/log4jtologback/ http://java.ihoney.pe.kr/397 https://logback.qos.ch/
μ΄μ κΉμ§ λ΄ κΈ°μ΅μΌλ‘λ Date κ΄λ ¨ ν΄λμ€λ₯Ό μλμ²λΌ μ μ°¨ λ°κΏμ¨μ¨κ±Έλ‘ κΈ°μ΅μ΄ λλ€. java.util.Date > java.util.Calendar > org.joda.time κ·Έλ°λ° java 8 λ²μ μμ κΈ°μ‘΄μ μμλ λ¬Έμ λ€μ κ°μ ν΄μ λμλ€κ³ νλ€. (λ€μ΄λ² HellowWorld ν¬μ€ν
μ°Έκ³ ) JSR-310 μ΄λΌλ νμ€λͺ
μΈλ‘.
μ§κΈλΆν°λ JAVA 8 μμ μ 곡νλ APIλ‘ λ μ§ μ°μ°μ μ΄λ»κ² νλμ§μ λν΄ μμλ³΄κ³ μ νλ€. (λ¬Όλ‘ μλ§μ λ μ§ μ°μ° λ°©λ²μμ΄ μμ§λ§ μμ£Ό μ°μ΄λ λΆλΆλ€ μμ£Όλ‘ μ 리ν΄λ³΄μ.)
Date > String (format) LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); String > Date (format) LocalDateTime.parse("2017-01-01 12:30:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); λ μ§/μκ° μ¦κ° LocalDateTime localDateTime = LocalDateTime.of(2017, 1, 1, 10, 0, 0); localDateTime.plusDays(1); // μΌ localDateTime.plusMonths(1); // μ localDateTime.plusHours(1); // μκ° localDateTime.plusWeeks(1); // μ£Ό localDateTime.minusYears(1); // λ
localDateTime.minusMinutes(1); // λΆ λ λ€μν λ΄μ©λ€μ μλ URL μμ νμΈμ΄ κ°λ₯νλ€. https://docs.oracle.com/javase/tutorial/datetime/iso/overview.html
μ§λλ²μλ νΈλμμ
μ μ€μ κ°μ λν΄ μμλ³Έ λ° μλ€. [ Spring Transaction μ΅μ
] μ΄λ² ν¬μ€ν
μμλ μ€μ λ‘ μ€νλ§ νκ²½μμ μ΄λ€μμΌλ‘ μ€μ ν΄μΌ @Transactional μ΄λ
Έν
μ΄μ
μ μ¬μ©ν μ μλμ§, κ·Έλ¦¬κ³ μ΄λ€ μμ±λ€μ΄ μλμ§μ λν΄ μμλ³΄κ³ μ νλ€.μ€μ κΈ°μ‘΄ xmlλ°©μμμλ λ€μκ³Ό κ°μ΄ μ€μ μ νλ€.
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/> νΉ, JavaConfig λ°©μμΌλ‘ μ€μ νκΈ° μν΄μλ λ€μκ³Ό κ°μ΄ μ€μ νλ€.
@EnableTransactionManagement public class AppConfig { ... @Bean public PlatformTransactionManager transactionManager() throws URISyntaxException, GeneralSecurityException, ParseException, IOException { return new DataSourceTransactionManager(dataSource()); } } μμκ°μ΄ μ€μ μ ν΄μ£Όλ©΄ νΈλμμ
μ μ€μ νκ³ μ νλ κ³³ μ΄λμλ @Transactional μ΄λ
Έν
μ΄μ
μ μ§μ ν΄μ μ μ©μ΄ κ°λ₯νλ€.
public class UserService{ @Transactional public boolean insertUser(User user){ ... } } μ£Όμμμ± @Transactional μ΄λ
Έν
μ΄μ
μ μ£Όμμμ±μ λ€μκ³Ό κ°λ€.
μμ± μ€ λͺ
μ¬μ© μ isolation Transactionμ isolation Level. λ³λλ‘ μ μνμ§ μμΌλ©΄ DBμ Isolation Levelμ λ°λ¦. @Transactional(isolation=Isolation.DEFAULT) propagation νΈλμμ
μ νκ·μΉμ μ μ , Default=REQURIED @Transactional(propagation=Propagation.REQUIRED) readOnly ν΄λΉ Transactionμ μ½κΈ° μ μ© λͺ¨λλ‘ μ²λ¦¬ (Default = false) @Transactional(readOnly = true) rollbackFor μ μλ Exceptionμ λν΄μλ rollbackμ μν @Transactional(rollbackFor=Exception.class) noRollbackFor μ μλ Exceptionμ λν΄μλ rollbackμ μννμ§ μμ. @Transactional(noRollbackFor=Exception.class) timeout μ§μ ν μκ° λ΄μ ν΄λΉ λ©μλ μνμ΄ μλ£λμ§ μμ κ²½μ° rollback μν. -1μΌ κ²½μ° no timeout (Default = -1) @Transactional(timeout=10) λ§μΉλ©° μμΉ« μλͺ»νλ€κ°λ μμΉμλ νΈλμμ
μΌλ‘ μλͺ»λ κ²°κ³Όλ₯Ό μ΄λν μ μκΈ°λλ¬Έμ κΈ°λ³Έκ°μ μμ§νλκ² μ’μκ² κ°λ€.
μλ§μ λΈλ‘κ±°λΆλ€μ λμμ λ°κ³ μ ꡬκΈλ§μ ν΄μ μ μ©μ ν΄λ΄€μ§λ§ λ무λ§μ μ½μ§μ νλ€.(ν΄λ΄€λ λ°©μμ jsonViewResolver λ₯Ό λ°λ‘ μ€μ ν΄λ³΄κ±°λ, @RequestMapping μ΅μ
μ λ°κΏλ³΄λ μμ€..) νΉνλ Springμ€μ λ°©μμ΄ μμ λ°©μμ΄μλ xmlμ΄ μλ javaconfigμκΈ° λλ¬Έμ λμ±λ μλ£κ° μμκ³ .. νμ°Έμ μ½μ§νλ€ ν΄κ²°μ νμ¬ ν¬μ€ν
νκ² λλ€. μ°μ νκ²½μ spring 4.3.4.RELEASE, Maven, jdk8μμ λ°νλ€.
pom.xml jackson-mapper-aslμ μ΄μ©ν΄μ νλΌλ λΈλ‘κ±°λ€λ μμμ§λ§, μ무리ν΄λ(λκ° Springλ²μ κ³Ό λ§μ§ μλλ― νλ€.) μ μλμ΄ μλμ κ°μ dependencyλ₯Ό μ£Όμλ€.
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.5.1</version> </dependency> Controller μλμκ°μ΄ @ResponseBody μ΄λ
Έν
μ΄μ
μ μ€μ ν΄μ£Όκ³ 리ν΄μ ν΄λΉ λͺ¨λΈμ λκΈ°λ©΄ λλ€.
@RequestMapping(value="/test") @ResponseBody public Map<String, Object> test(){ Map<String, Object> map = new HashMap<String, Object>(); map.put("1", "111"); map.put("2", 222); return map; } κ·Έλ¦¬κ³ νΈμΆμ ν΄λ³΄λ©΄ κΈ°λνλκ²μ²λΌ μ΄μκ² jsonννλ‘ λμ¨λ€.
{ "1": "111", "2": 222 } λ¬Όλ‘ , list λ array, μΌλ° κ°μ²΄λ κ°λ₯νλ€.
μ 리 μ½μ§μ λμ μκ²λ μ¬μ€(?)μ μ 리ν΄λ³΄μ. λ€λ₯ΈμΈ‘λ©΄μμ λΆμμ ν΄λ³΄λ©΄. @ResponseBodyμ μ΄μ©νμ¬ view μ json ννλ‘ λνλ΄κ³ μ ν κ²½μ° κ°λ₯ν μν©μ toStringμΌλ‘ νμλ jsonννλ‘ λμ¬μ μμΌλ©΄ κ°λ₯νλ€. μλ‘λ€μ΄ μλμ²λΌ ν΄λμ€μ Lombok μ΄λ
Έν
μ΄μ
μΈ @Dataκ° λΆμΌλ©΄ μλμΌλ‘ toStringμ μ€λ²λΌμ΄λ© ν΄μ£ΌκΈ° λλ¬Έμ ν΄λΉ ν΄λμ€λ₯Ό 리ν΄νκ²λλ©΄ μλμΌλ‘ json μ²λ¦¬κ° λλ€.
@Data public Student{ private String id; private String name; ... } @ResponseBodyμ λΆμ΄κ³ List<Student>λ₯Ό 리ν΄νκ² λλ©΄ μλ¬κ° λλλ°, μ΄λ΄κ²½μ° λ³λ λΌμ΄λΈλ¬λ¦¬λ₯Ό μΆκ°ν΄μ€μΌ μλμΌλ‘ λ³νλμ΄ json ννλ‘ λμ¬μ μκ² λλ€. (list.toStringμ νλ©΄ jsonννκ° μλ μ΄μν λ¬Έμννλ‘ λμ€κΈ° λλ¬Έ… Mapκ°μκ²λ λ§μ°¬κ°μ§ μ΄μ λ‘ λ³λ λΌμ΄λΈλ¬λ¦¬λ₯Ό μΆκ°ν΄μ€μΌ μ μμ μΌλ‘ λμ¨λ€.)
λ§μΉλ©° λ¨μν @ResponseBodyλ₯Ό μ¬μ©ν΄μ jsonμΌλ‘ 리ν΄νλ €λ©΄ μ΄λ€ λΌμ΄λΈλ¬λ¦¬λ₯Ό μΆκ°ν΄μΌνλ€ λ‘ μκ°νλκ²μμ, μ΄κ²μ κ² ν
μ€νΈ ν κ²°κ³Ό toStringμ ν μ μμ΄μΌ νκ³ κ·Έ κ°μ΄ jsonννμ΄λ©΄ κ°λ₯νλ€ λ‘ κ²°λ‘ μ΄ μ§μ΄μ‘λ€. νμ€ν μ₯λ μ½λΌλ¦¬ λ§μ§λ―μ΄ ‘κ·Έλ°κ°λ³΄λ€’νκ³ λμ΄κ°λ©΄ μ½μ§μ΄ μ§μ§ λΆνμν μ½μ§μ΄ λλκ² κ°λ€. ꡬκΈλ§μ ν΄λ³΄κ³ , ν
μ€νΈλ₯Ό ν΄λ΄μ, κ²°λ‘ μ μΌλ‘ λ΄κ²μΌλ‘ λ§λλ μ΅κ΄μ κ°μ ΈμΌ κ² λ€.
1. λλ ν°λΈλ°©μ <%@ include file="~~"%> μ μ include λ°©μ, μΈν΄λ£¨λ λλ λ΄μ©μ΄ λ¨μνκ² ν
μ€νΈλ‘ ν¬ν¨λμ΄ μ»΄νμΌμ΄ λλ€. (볡μ¬λλ€λ λλ) μ£Όμν μ μ λΉλ‘ ν¬ν¨λλ νμ΄μ§λΌ νλλΌλ νκΈμ μ λλ‘ μ²λ¦¬νκΈ° μν΄μλ ν¬ν¨λμ΄μ§λ jspνμΌ μλ¨μ μΈμ½λ© λͺ
μλ₯Ό ν΄μ€μΌ νλ€. ν¬ν¨λμ΄μ§λ jsp λ΄μ©μ΄ λ³κ²½μ΄ λ κ²½μ° ν΄λΉ jspλ₯Ό μ¬μ©νλ jspλ₯Ό κ°μ λ‘ λ³κ²½(touch) ν΄μ€μ λ€μ μ»΄νμΌμ΄ λκ² ν΄μΌνλ λΆνΈν¨μ΄ μλ€. μ μ λ°©μμ΄κΈ° λλ¬Έμ μλ‘λ€μ΄ μ μλ³μλ₯Ό μΈν΄λ£¨λ λλ jspμμ μ§μ νκ² λλ©΄ μμjspμμ μ¬μ©μ΄ κ°λ₯νκ² λλ€. 2. μ‘μ
νκ·Έ λ°©μ <jsp:include page="~~"/> λμ include λ°©μ, ν¬ν¨νλ λ¬Έμμ μκ΄μμ΄ λμ μΌλ‘ μ»΄νμΌ λλ€. (μμ ν λ³λλ‘ λμνκΈ° λλ¬Έμ λ³μλ₯Ό λμμ μ¬μ©νλ €λ©΄ λ°λ‘ νλΌλ―Έν°λ‘ λ겨μ€μΌ νλ€.) flush μ΅μ
μ μμ²νλ¦μ΄ λμ΄κ°λ©΄μ νμ¬κΉμ§ νμ΄μ§μ κ²°κ³Όλ₯Ό μΆλ ₯ν κ²μΈμ§ λ§κ²μΈμ§λ₯Ό κ²°μ νλκ²μ΄λ€. μΌλ°μ μΌλ‘ falseλ‘ μ€μ νλ€. <jsp:param>λ₯Ό μ΄μ©νμ¬ νλΌλ―Έν°λ₯Ό μ μ‘ν μ μλ€. <jsp:include page="..." flush="false"> <jsp:param name="name" value="μ΄λ¦" /> <jsp:param name="pageName" value="νμ΄μ§μ΄λ¦"/> </jsp:include> 3. JSTL λ°©μ <c:import url="~~" /> JSTL(JSP Standard Tag Library) νκ·Έμ€μ νλ μ»΄νμΌ λκ³ λμνλ λ°©μμ μ‘μ
νκ·Έ<jsp:include page="~~"/>μ κ°μ νμ¬ μ»¨ν
μ΄λ μμ μλ μμμΈμ λ€λ₯Έ μΈλΆ μμλ ν¬ν¨μ΄ κ°λ₯νλ€. <c:import url="http://www.google.com/"/> μλμ κ°μ΄ λ³΄λ€ λ λ€μν μ΅μ
μ΄ μ 곡λλ€ <c:import! url="μ½μ΄μ¬ URL" var="μ½μ΄μ¬ λ°μ΄ν°λ₯Ό μ μ₯ν λ³μλͺ
" scope="λ³μμ 곡μ λ²μ" varReader="리μμ€μ λ΄μ©μ Reader κ°μ²΄λ‘ μ½μ΄μ¬ λ μ¬μ©" charEncoding="μ½μ΄μ¨ λ°μ΄ν°μ μΊλ¦ν°μ
μ§μ " />
μ¬ν΄λ μ΄κΉμμ΄(?) 1μ 1μΌμ΄ λμ΄ ν΄λ§μ΄(ν΄λμΈμ§ ν΄λ§μΈμ§ νκ°λ¦¬μ§λ§, μν΄ μ²«λ λΆν° 볡μ‘ν΄μ§κΈ° μ«λΉ =γ
=)λ₯Ό λ€λ
μ€κ³ κΉνμμ μν΄ κ³νμ μΈμλ³Έλ€. μ λ§ μ§ν¬μ μλ κ³νλ€, νμ€μ μΈ λΆλΆλ€λ§ κ³ λ €ν΄μ μ¨λ΄λ € κ°λ³΄μ. μ λ° μ΄μλ§μ΄λΌλ μ§ν¬μλ§ μλ€λ©΄ κ·Έλλ§ λ€νμ΄λΌκ³ μκ°!
κΈ°μ λΈλ‘κ·Έ μ΄μνκΈ° : μ 2ν posting
λ΄κ° μλμ§μμ΄ μΌλ§νΌμΈμ§, 보μ¬μ£ΌκΈ°μμ΄ μλ λ΄ λ¨Έλ¦Ώμμ μ리μ‘κ³ μλ λΆλΆλ€μ μ 리ν΄μ κΈ°λ‘ν νλ μ΄λ¦νμΌ κΈ°μ λΈλ‘κ·Έλ₯Ό μμ±νλκ±°λ€. 2μ£Όμ μ΅μ νλμ©, μ΄λ κ² λλ©΄ νλ¬μ μ΅μ 2post, 1λ
μ΄λ©΄ μ½ 20post. μλ€κ³ ν΄λ λ§λ₯ μκ²λ§ λκ»΄μ§μ§ μμ λΆλμ΄λ€. μ¬μνκ±° νλλΌλ. μ΄λ₯Όν
λ©΄ μλ² μ€μΉλ μ€νλ§μ κΈ°λ³Έ μ€μ κ΄λ ¨λ κ²λ€λ. κΈμ°λ μ°μ΅λ νκ³ μ’μ κΈ°νκ° λ κ² κ°λ€.
4λκ° μ’
μ£Ό : μμ°κ°, 1λ°2μΌμ½μ€
2014λ
μ νκ°(λΆνκ°, λ¨νκ°), 2015λ
μ κΈκ°, 2016λ
μλ λͺ»κ°λ€. 4λκ° μ’
μ£Όμ λͺ©νκ° κ°μκΈ° μλ€μ΄μ§ μλ
μ΄λΌ μκ°μ΄ λ λ€. μ°μ¬κ³‘μ μ°μ μμ λ€κ²ͺμ λ΄ μμ κ±° λΆλΆμ΄μκ² λ―Έμνμ§ μκΈ°μν΄μλΌλ μ¬ν΄ μ¬λ¦μλ κΌ μμ°κ°μ΄λ λλκ° νλλ₯Ό κ³νμ‘μ 1λ°2μΌ μ½μ€λ‘ λ€λ
μμΌκ² λ€. μ, λλ΅ 5μ? μλ§ μμ°κ°μ κ°κ²λ κ²κ°λ€. μ΄λ²μλ 무리νμ§ μκ³ 1λ°2μΌμ½μ€λ‘..
λ
μ : μ μ 곡1κΆ, μ 곡μΈ1κΆ
μλ
μ λ΄ μ
μμ λμλ μ΄μΌκΈ°λ€μ€μ νμ¬μ€λ½κ²(?)λμ¨ λ©νΈμ€ κ°μ₯ λ§μ΄λμλ μ±
μ’μ½μ μ¬ν΄μλ μ λ§ λ§μ΄λ μλμ§λΌλ μμ£Όμ½λ μ΅κ΄μ κΈΈλ¬μΌκ² λ€. νλ¬μ μ 곡μ±
νκΆ, κΈ°νμμ νκΆ. μμμ±
+μ½κ³ μΆμμ±
λΆν° μ½κΈ° μμν΄μ λ΄λ
1μ1μΌλλ λ΄ μ±
μ νμΌ μ μ리μ‘κ³ μλ μ±
μ₯μ κ°λ λ©μλ³΄κ³ μΆλ€. μ, λ¬Όλ‘ λ€ μ½μ μ±
λ€λ‘λ§.
μ¬ν+μ¬μ§ : νλ¬μ νλ²μ΄μ μ¬νκ°κΈ°
ν΄μΈλ κ΅λ΄λ , μ¬ν΄λ μ λ§ λ§μ΄ λ€λ
μμΌκ² λ€. κ°λ³κ² λΉμΌμΉκΈ°λΆν° μμν΄μ κ°μλ§ μλ€λ©΄ ν΄μΈμ¬νλ. λ¬Όλ‘ μ¬ν΄λ μΌκ·Όκ³Όμ μΈμμ κ³μλ ν
μ§λ§ μ£Όλ§ μ κΉμ΄λΌλ μκ°μ λ΄μ λλ¬μ?μλ νλ¬μ νλ²μ΄λΌλ ν΄κ°λ₯Ό μ¨μλΌλ κ°κΉμ΄κ³³μ νλ§νλ¬ λ€λ
μ€κ³ μΆλ€. κ°μ μλ
μ μ° μΉ΄λ©λΌλ‘ μ¬μ§λ μ΄κ²μ κ² λ§μ΄ μ°κ³ μ’μμΆμ΅ λ§μ΄ λ§λ€κ³ μ€κ³ μΆλ€.
μ μΆ+a : κ·Όκ²μ μ½μ μνν, κ²½μ 곡λΆ
λλ¦ μκΈμ 60%μ΄μμ μ μΆνλ μ€μ΄λ€. κ·ΈμΉλ§ μν©μ΄ μν©μΈμ§λΌ μ§κΈλ λ§μ‘±νμ§ λͺ»νλ€. μ²μ₯μ κ΅΄λΉ λ¬μλκ³ κ°μ₯μ°μ΄ λ¨Ήλλ€λκ² μλλΌ μλμ μλ λΆλΆλ€μ μ΅λν μλΌλ©΄μ μ΄μλκ±°λ€. μμΉ¨μ νμ νμ§λ§κ³ μ‘°κΈ μΌμ° μΌμ΄λμ λ²μ€λ₯Ό νλ€λμ§, λ²μ€λ₯Ό νμ§λ§κ³ μ‘°κΈμΌμ° μΌμ΄λμ μμ κ±°λ₯Ό νλ€λμ§(μ¬μ€ μμ κ±°λ₯Ό νλ©΄ ν΄κ·Όν λ λ λΉ λ₯΄κ³ νΈνκ² μ¬μ μμΌλ) μνμμμ μ μ½ν μ μλ λΆλΆλ€μ μ°Ύκ³ , λͺΈμ λ² λλ‘ μ΅κ΄ν μμΌμΌκ² λ€. κ·Έλ¦¬κ³ μ£Όμμ΄λ νλ λ± ν¬μμ λν΄μλ μ΄μ 곡λΆλ₯Ό ν΄λ΄μΌκ² λ€. (λ
μνμλκ±°λ λΉμ·ν μ΄μΌκΈ°) μ κΈλ¦¬μλ λ§λ₯ μ μΆλ§ νλ€λ³΄λ©΄ νλ 건 λꡬλ λ€ μλμ΄μΌκΈ°. μΌμ μΉμ¬ μνμ μΉμ¬ νκ³λμ§λ§κ³ λ°°μκ°λ©΄μ μ±κ²¨λ³΄μ.
μ΄λ : μμ νλ§μ€ν°, λͺΈμ§±
νμ νλ μ΄μΌκΈ°μ§λ§ 건κ°λ³΄λ€ μ€μν건 μλ€κ³ μκ°νλ€. μ¬ν΄μλ λ³μκ°μ§ μλ λλ₯Ό λ§λ€κΈ° μν΄ ν¬μ€ + λ°°λλ―Όν΄ + λΌμ΄λ© μ νμκ³ κ°λ₯νλ©΄ μμλ λ°°μμ μμ ν μ λλ ν μμλ λλ₯Ό λ§λ€κ³ μΆλ€. κ·Έλμ λ€λ€ λ§νλ λͺΈμ§±λ λλ³΄κ³ μΆκ³ μμ μκ² ν΄λ³κ°μμ μμλ₯Ό νμν μμλ(?!) 건κ°ν λ΄κ° λλλ‘ λ
Έλ ₯ν΄μΌκ² λ€.
λ΄μ¬νλνκΈ° : μ°νλ°°λ¬, μμλ΄μ¬
μλ
μ νλ €λ€κ° λͺ»ν λ΄μ¬νλ μ¬ν΄λ κΌ ν΄μΌκ² λ€. κ°κΉκ² ν μμμλ²νκ² μ°νλ°°λ¬, μ΄κ±΄ 1μλ¬ λ΄λ‘ κΌ! ν΄μ λ΄μ¬λΌλκ²κ³Ό λλμ΄λΌλ ν볡μ λκ»΄λ³΄κ³ μΆλ€. μ§κΈ μκ°λλ건 μμλ΄μ¬ κ°μκ²λ ν΄λ³΄κ³ μΆκ³ 무보μ μλ°(?) κ°μκ²λ ν΄λ³΄κ³ μΆλ€. λμ΄λ€λ©΄ λͺ»ν , μΈμ ν΄λ³΄κ² λ.
κ°κΉμ΄, λ¨Ό μ¬λλ€ λ§λκΈ°
λ§μ§λ§μΌλ‘, μκ³ μμλ μ€μν νλ. λ°λ‘ μ¬λλ€ λ§λκΈ°λ€. λ°μλ€λ νκ³ νλλ§μΌλ‘ λ±νμν λ΄ μμ€ν μ¬λλ€. μ무리 μ°λ΄μ λ§μ΄ λ°κ³ μΌμ μνλ€κ³ νμ¬μμ μλκ°λ€ ν μ§λΌλ, λ΄ κ³μ λλ₯Ό μκ°ν΄μ£Όλ μμ€ν μ¬λλ€μ΄ μκΈ°μ λ΄κ° μμμ μλκ² κ°λ€. κ°κΉμ΄ μ¬λλ€λΆν° μμν΄μ μ€λ¬λμ λͺ»λ΄€λ μ¬λλ€λ νλλμ© μ°λ½νλ©΄μ μ§λ΄λ μ¬μ λ₯Ό κ°μ ΈμΌ κ² λ€.
ν μ μμκΉ? λΌλ μκ°λ³΄λ€ νλλμ© μμ§λ§κ³ , λμΉμ§ λ§κ³ ν루λ₯Ό, μ΄λ²μ£Όλ₯Ό, μ΄λ²λ¬μ μ κ²νκ³ μ€μ²ν΄ λκ°λ³΄μ. μ¬ νν΄λ μ΄μ¬ν μ΅μ μ λ€ν΄ μ΄κ²!
2016λ
, λ΄κ² μ λ§ μλ§μ μΌλ€μ΄ μμκ³ κ·Έ μ΄λλλ³΄λ€ (μ μ νλ‘) λ―ΈμΉλ―μ΄ νμ¬μ μ§μ€νλ μκ°λ€λ‘ κΈ°μ΅λλ€. 무μμ λ€κ°μ€λ μν΄λ₯Ό λ§μ΄νλκ²λ μ’μ§λ§ μ¬ νν΄λ₯Ό λλμ보λ μκ°μ κ°κ³ , λλ₯Ό λ€μ μ κ²ν΄λ³΄λ μ°¨μμμ μΌλͺ
‘νκ³ ’λ₯Ό ν΄λ³ΌκΉ νλ€.
νμ¬ μ λ§ μ΄μ¬ν νλ€. μνλμ§λ… μ λͺ¨λ₯΄κ² λ€. λ μνκ² κ°λ€. λ¬Όλ‘ λ΄ ν루μ€μ κ°μ₯λ§μ μκ°μ μμκ²λ μμ§λ§ μλ
μ λ§μ΄ νμ§ λͺ»νλκ²μ ‘λ μ¨’λΌλ μλΉμ€λ₯Ό νλ‘ λ§‘μΌλ©΄μ μ λ§ λ§μκ²μ λ°°μ°κ³ κ²°κ³Όλ¬Όλ νννμ§ μμλ§νΌ λμ¨κ² κ°λ€. μ§λκ³ λ³΄λ©΄ κ΅¬μ§ νμ§ μμλ μκΈμ λκ°μ΄ λμ¬ν
κ³ , μν€μ§λ μμλλ° κ·Έμκ°μ μ μ λ μ€μΌλ©΄ νλ μκ°λ λ€μ§λ§ νννμ§ μλλ€. μ무λ μλ μ¬λ¬΄μ€ λνΌμ 12μλμ΄μ ν΄κ·Όμ ν΄λ μ¦κ±°μ μΌλκΉ, κ·Έκ±°λ©΄ λ¬λ€. λͺ¨λ°μΌ κ°νΈμ΄λΌλ ν° μ
무λ₯Ό 무μ¬ν(?) ν΄μ³λ΄κ³ λ μ¬λ΄μμ μ‘°μ§(μλΉμ€)μ λ³κ²½ν μ μλ κΈ°νκ° λμ΄ λνλ‘ μ§μ, λ€νμ€λ½κ²λ ν©κ²©μ ν΄μ μ§κΈμ λ€μ΄λ²νμ΄ μ κ΄λ ¨λ μΌμ νκ³ μλ μ€μ΄λ€. κΈ°μ‘΄ μλΉμ€μ΄μμ νλ©΄μ λλΌμ§ λͺ»νλ, μ΄κΈ° μ€κ³λΆν° μμνμ¬ μ΄λ€ κΈ°μ μ€νμ μΈκ²μΈκ°μ λν μ νλΆν° λ€μν μνμ°©μ€λ₯Ό ν΅ν΄ μ΄μ ν λλ¬ λμλλ° μ λ§ λ§μ΄ λ°°μ°κ³ μλ€. λ무 νλ€μ§λ§ λ무 ν볡νλ€. λμ΄μΌλ³΄λ©΄ μμ¬μΌμΌλ‘ κ°λ° κ΄λ ¨λ 곡λΆλ₯Ό λ±νμ νκ² λ무 ννκ° λλ€. λ°μλ€λ μ΄μ νλλ§μΌλ‘ (μμ§ν λ°μλ€λ건 νκ³λ€) κΈ°λ₯ꡬνμλ§ μ κ²½μ μ¨μλλ°, λ΄λ
λΆν°λ ν μλ§ μλ€λ©΄ μ
무 μΈμ μΌλ‘ λλ§μ κ°λ°νΈλ¦¬λ₯Ό μΈμλ³΄κ³ μΆλ€.
κ±΄κ° μΌμ£ΌμΌμ νλ² μ΄μ μ€μ μ λ°°λλ―Όν΄, μ λ
μ ν¬μ€μ₯μ κ°λ €κ³ λ
Έλ ₯νλ€. κ·Έ κ²°κ³ΌμμκΉ, μ¬λλ λΊκ±° λ§κ³ λ λ³μμ λ¨νλ²λ μκ°λ€. κ°κΈ°μ‘°μ°¨ κ±Έλ¦¬μ§ μλκ² λ€νμ΄λΌκ³ μκ°νμ§λ§, μμ¦λ€μ΄(μΌκ·Όμ΄ λ§μμ ΈμμΈμ§) μ±
μμ μμμλ μμΈκ° λΆλν΄μ κ±°λΆλͺ©μ΄ λκ°κ³ μλ€. νΌλ‘€λ¬λ ꡬλΉνκ³ μ΄κΉ¨ ν΄μ§λΌκ³ λ°΄λλ ꡬμ
ν΄μ μ¬μ©μ νλλ° μ μ€μ²μ΄ μλλ μ€μ΄λ€. μλ
μ μμ κ±°λ₯Ό μμ΄λ²λ¦¬λ€ λμ°Ύκ³ λ μμ κ±°λ₯Ό λ±νμ νκ² λλκ² κ°λ€. μ΄λν νκ³κ² μ§. λ΄λ
μ κΌ 4λκ°μ€ νλ μ‘κ³ μ’
μ£Όνλ² ν΄μΌκ²λ€. κΈ°νμ½.. μλ§λ€ μμλ. γ
γ
λ¬Όμ λ¨μ§ μμΌλ ν°μΌμ΄λ€…
μ¬λκ΄κ³ νκ΅μ νλ°°λκΈ° λ° λμ리 μ¬λλ€, κ΅°λ λκΈ°λ€ λ° μλμλ€ κ³Ό μ μ μ₯κ΅λΆλ€, κΈ°ν λ±λ±… μ¬ν΄ λ€μ΄μμΈμ§. μ°λ½μ λ무 무μν λ§νΌ μκ³ μ΄μλκ² κ°λ€. μ§λκ³ λ³΄λ©΄ λ€λ₯Έκ³³μ μ κ²½μ΄λ€κ³ μ°λ½μ λͺ»νλ€κ³ νκ³λ₯Ό λκ³ μλ λμ΄μ§λ§, λ ννΈμΌλ‘λ κ·Έ μ°λ½ 10λΆ μκ°μ΄ μλ€λ건 … μμλ νκ³λ€. λλ₯Ό λμμ£Όκ³ λλ₯Ό λ―Ώμ΄μ£Όκ³ λλ₯Ό μκ°ν΄μ£Όλ μ¬λλ€μ μ‘°κΈμ΄λΌλ λ μ κ²½μ¨μ μ°λ½νκ³ μ°Ύμ λ΅λ μκ°μ λ΄λ
λΆν°μλΌλ κ°μ ΈμΌκ² λ€.
λ§μΉλ©° μΌλ¨ 첫λ²μ§Έλ‘ λ΄λ
λΆν° ν μΌμ, κΈ°μ λΈλ‘κ·Έλ₯Ό μ΄μνλκ²μ΄λ€. μμ§ν λλ¬μ μ΄ gitHub λ₯Ό μ΄μ©ν΄μ λΈλ‘κ·Έλ₯Ό λ§λ€κΈ΄ νμ§λ§ κ·Έλ₯ ν¬μ€ν
λ λͺ»νκ³ λ°©μΉ μμ€μ΄μμΌλ… μ μ΄λ νλ¬μ νλκ° μ λλ ν¬μ€ν
ν΄λ³΄λ €κ³ λ
Έλ ₯ν΄μΌκ²λ€. κΈμ°λκ² νλ€κ³ μκ°μ΄ λ§μ΄ λ€μ΄κ°λ μμ
μ΄μ§λ§, λμ΄μΌ μκ°νλ©΄ λ€ λ΄ μμ°μ΄κ³ λλ₯Ό λ€μ λ°λΌλ³Όμ μλ κΈ°νλκΉ. κΌ κΈ°μ λΈλ‘κ·Έλ§μ΄ μλ, ν루λ₯Ό κΈ°λ‘νλ 무μΈκ°λ₯Ό ν΄μΌκ² λ€. λ§μ νν΄λ₯Ό λμ΄μΌλ³΄λ κ·Έλλ λνλμ§ κΈ°μ΅λ μλλ€.. λλ²μ§Έλ‘λ μ§ν¬μ μλ κ³νμ μ‘λκ²μ΄λ€. μ¬ νν΄ λͺ©νμ€μ μ΄λ£¬κ±΄ 10κ°μ€μ λ¨ λκ°… (κ·Έμ€μ λ
Έλλνλκ°κΈ°, μ€μΏ λ²λ€μ΄λΉ νκΈ°, μμ ν λ§μ€ν°νκΈ°λ μλ€;;) λΆλλ½λ€..
2016λ
, λλΌλ λ€μμ νκ³ μ μ μλ νν΄μμ§λ§ λλ¦ μλ―Έμλ μκ°λ€μ 보λΈκ² κ°μ λ€νμ΄λΌ μκ°νλ€. μ,. 10μ λ§μ μ 8μ ?? 2017λ
! λ€μνλ² μΌμ΄μμ! νμ΄ν
!!
μν© μ€νλ§ νκ²½μμ μΌλ°μ μΌλ‘ DAO λ BO λ 벨μμ λ€μκ³Ό κ°μ΄ μ½λ©μ νκ² λλ€.
@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED, rollbackFor = Exception.class) public int method(int i) throws Exception { return sqlMapClient.delete("~~~~"); } 무λΆλ³νκ² Ctrl+C,V μ 곡μΌλ‘ νΈλμμ
μ΄λ
Έν
μ΄μ
μ κ°μ Έλ€κ° μ¬μ©ν μλ μκ² μΌλ, κ° κ°λ€μ΄ μ΄λ€ μνμ μλμ§μ λν΄ μκ³ λμ΄κ° νμμ±μ΄ μλ€.
@Transactional μ°μ ν΄λΉ μ΄λ
Έν
μ΄μ
μ μ μ©νλ©΄ μ μ©λ ν΄λμ€ λλ λ©μλμ νΈλμμ
μ΄ μ μ©λλ€. λ°λΌμ λ‘μ§ νλ¦μ λ§μΆμ΄ μ 체μ μΌλ‘ νΈλμμ
μ μ μ©ν κ²μΈμ§, μλλ©΄ νΉμ λ©μλμ μ μ©ν κ²μΈμ§ μ λ΅μ μ μΈμμΌ νλ€.
isolation 격리μμ€μ΄λΌλ μ΅μ
μ΄λ€. νΈλμμ
μμ μΌκ΄μ±μ΄ μλ λ°μ΄ν°λ₯Ό νμ©νλλ‘ νλ μμ€μ λ§νλλ° μ΅μ
μ λ€μκ³Ό κ°λ€.
READ_UNCOMMITTED (level 0) νΈλμμ
μ μ²λ¦¬μ€μΈ νΉμ μμ§ μ»€λ°λμ§ μμ λ°μ΄ν°λ₯Ό λ€λ₯Έ νΈλμμ
μ΄ μ½λ κ²μ νμ© μ΄λ€ μ¬μ©μκ° AλΌλ λ°μ΄ν°λ₯Ό BλΌλ λ°μ΄ν°λ‘ λ³κ²½νλ λμ λ€λ₯Έ μ¬μ©μλ BλΌλ μμ§ μλ£λμ§ μμ(Uncommitted νΉμ Dirty) λ°μ΄ν° Bλ₯Ό μ½μ μ μλ€. Dirty read : μμ κ°μ΄ λ€λ₯Έ νΈλμμ
μμ μ²λ¦¬νλ μμ
μ΄ μλ£λμ§ μμλλ°λ λ€λ₯Έ νΈλμμ
μμ λ³Ό μ μλ νμμ dirty read λΌκ³ νλ©°, READ UNCOMMITTED 격리μμ€μμλ§ μΌμ΄λλ νμ
READ_COMMITTED (level 1) dirty read λ°©μ§ : νΈλμμ
μ΄ μ»€λ°λμ΄ νμ λ λ°μ΄ν°λ§μ μ½λ κ²μ νμ© μ΄λ ν μ¬μ©μκ° AλΌλ λ°μ΄ν°λ₯Ό BλΌλ λ°μ΄ν°λ‘ λ³κ²½νλ λμ λ€λ₯Έ μ¬μ©μλ ν΄λΉ λ°μ΄ν°μ μ κ·Όν μ μλ€. REPEATABLE_READ (level 2) νΈλμμ
μ΄ μλ£λ λκΉμ§ SELECT λ¬Έμ₯μ΄ μ¬μ©νλ λͺ¨λ λ°μ΄ν°μ shared lockμ΄ κ±Έλ¦¬λ―λ‘ λ€λ₯Έ μ¬μ©μλ κ·Έ μμμ ν΄λΉλλ λ°μ΄ν°μ λν μμ μ΄ λΆκ°λ₯νλ€. μ ν νΈλμμ
μ΄ μ½μ λ°μ΄ν°λ νΈλμμ
μ΄ μ’
λ£λ λκΉμ§ νν νΈλμμ
μ΄ κ°±μ νκ±°λ μμ νλ κ²μ λΆνν¨μΌλ‘μ¨ κ°μ λ°μ΄ν°λ₯Ό λ λ² μΏΌλ¦¬νμ λ μΌκ΄μ± μλ κ²°κ³Όλ₯Ό 리ν΄ν¨ SERIALIZABLE (level 3) μλ²½ν μ½κΈ° μΌκ΄μ± λͺ¨λλ₯Ό μ 곡 λ°μ΄ν°μ μΌκ΄μ± λ° λμμ±μ μν΄ MVCC(Multi Version Concurrency Control)μ μ¬μ©νμ§ μμ(MVCCλ λ€μ€ μ¬μ©μ λ°μ΄ν°λ² μ΄μ€ μ±λ₯μ μν κΈ°μ λ‘ λ°μ΄ν° μ‘°ν μ LOCKμ μ¬μ©νμ§ μκ³ λ°μ΄ν°μ λ²μ μ κ΄λ¦¬ν΄ λ°μ΄ν°μ μΌκ΄μ± λ° λμμ±μ λμ΄λ κΈ°μ ) νΈλμμ
μ΄ μλ£λ λκΉμ§ SELECT λ¬Έμ₯μ΄ μ¬μ©νλ λͺ¨λ λ°μ΄ν°μ shared lockμ΄ κ±Έλ¦¬λ―λ‘ λ€λ₯Έ μ¬μ©μλ κ·Έ μμμ ν΄λΉλλ λ°μ΄ν°μ λν μμ λ° μ
λ ₯μ΄ λΆκ°λ₯νλ€. propagation ( μ νμ΅μ
) REQUIRED : λΆλͺ¨ νΈλμμ
λ΄μμ μ€ννλ©° λΆλͺ¨ νΈλμμ
μ΄ μμ κ²½μ° μλ‘μ΄ νΈλμμ
μ μμ± REQUIRES_NEW : λΆλͺ¨ νΈλμμ
μ 무μνκ³ λ¬΄μ‘°κ±΄ μλ‘μ΄ νΈλμμ
μ΄ μμ± SUPPORT : λΆλͺ¨ νΈλμμ
λ΄μμ μ€ννλ©° λΆλͺ¨ νΈλμμ
μ΄ μμ κ²½μ° nontransactionallyλ‘ μ€ν MANDATORY : λΆλͺ¨ νΈλμμ
λ΄μμ μ€νλλ©° λΆλͺ¨ νΈλμμ
μ΄ μμ κ²½μ° μμΈκ° λ°μ NOT_SUPPORT : nontransactionallyλ‘ μ€ννλ©° λΆλͺ¨ νΈλμμ
λ΄μμ μ€νλ κ²½μ° μΌμ μ μ§ NEVER : nontransactionallyλ‘ μ€νλλ©° λΆλͺ¨ νΈλμμ
μ΄ μ‘΄μ¬νλ€λ©΄ μμΈκ° λ°μ NESTED : ν΄λΉ λ©μλκ° λΆλͺ¨ νΈλμμ
μμ μ§νλ κ²½μ° λ³κ°λ‘ 컀λ°λκ±°λ λ‘€λ°±λ μ μμ. λλ¬μΌ νΈλμμ
μ΄ μμ κ²½μ° REQUIREDμ λμΌνκ² μλ no-rollback-for - μμΈμ²λ¦¬ (κΈ°λ³Έκ° : μμ) νΉμ μμΈκ° λ°μνλλΌλ λ‘€λ°±λμ§ μλλ‘ μ€μ
μ€νλ§ λ°°μΉμμμ νΈλμμ
(λ΄κ° λΉνλ(?) λ¬Έμ ) μ€νλ§ λ°°μΉμμλ Tasklet μμ κΈ°λ³Έμ μΌλ‘ step λ¨μ νΈλμμ
μ μ§μνκ³ μλ€κ³ νλ€. κΈ°λ³Έμ μΌλ‘ jobμ΄ νλμ tasklet μ step μΌλ‘ μ€ννλ€λ³΄λ λͺ
μμ μ΄μ§ μμ§λ§ λ΄λΆμ μΌλ‘ μ 체 νΈλμμ
μΌλ‘ κ±Έλ €μκ² λλ€. λκ°μ job λ΄ DAO delete λ©μλμμ @Transactional μ€μ μ νκ³ κ·Έ DAO λ©μλλ₯Ό λ°λ³΅λ¬Έμ μν΄ delete νλ λ‘μ§μ μννλ λΆλΆμ΄ μμλλ° λΆλͺ¨μ νΈλμμ
(taskletμμ μ€μ λ νΈλμμ
)μΌλ‘ μΈν΄ dao λ₯Ό λͺλ² νΈμΆνλ jobλ¨μλ‘ νΈλ μ μ
μ΄ κ±Έλ¦¬κ² λμλ€. (κ²°κ΅ νΈλμμ
μ λ°λ³΅λ¬Έμ΄ λ€ λλμΌ μ μ©μ΄ λλ€λμ .) κ·Έλ¬λ€λ³΄λ κ°λ DB Query Lockμ΄ κ±Έλ Έλλ° DBλ 벨μμ undologλ₯Ό λ¨κΈ°λκ² λ무 무거μμ Έ lockμ΄ λ°μ
λ°λΌμ μ νμ΅μ
μ μμ ν΄μ ν΄λΉ λ¬Έμ λ₯Ό ν΄κ²°νμλ€.
# κΈ°μ‘΄ begin delete < for λ°λ³΅λ¬Έ commit # μ νμ΅μ
μμ (κΈ°μ‘΄ REQUIRES μμ REQUIRES_NEW μΌλ‘ μμ ) for begin delete commit for end
λμμΈ ν¨ν΄μ€μ κ°μ₯ μ μλ €μ§ μ±κΈν€ μ λν΄μ μμλ³΄κ³ μ νλ€. λ©ν° μ€λ λ νκ²½μμ μμ£Ό μ΄μ©λλ ν¨ν΄μ΄λΌκ³ λ§ λ€μλλ° μ΄λ² κΈ°νλ₯Ό ν΅ν΄ μ λλ‘ μ 리ν΄λ³΄μ
μ±κΈν€μ΄ 무μμΈκ° μ±κΈν€(Singleton)μ μ νν νλμ μΈμ€ν΄μ€λ§ μμ±λλ ν΄λμ€μ΄λ€.
λΌκ³ μ΄νν°λΈ μλ°μμ μ μλμ΄μλ€. μ¦, λ± νλλ§ μμ±νκ³ μ΄λ₯Ό μ¬κΈ°μ κΈ°μ μ¬μ©νλ ν¨ν΄μ΄λΌ μκ°νλ©΄ λ λ― νλ€. μ±κΈ μ€λ λ νκ²½μμλ λΉμ°ν μΈμ€ν΄μ€λ₯Ό 곡μ ν μν©μ΄ μκ² μ§λ§ λλΆλΆ λ©ν° μ€λ λ νκ²½μ΄κΈ° λλ¬Έμ μ±κΈν€ ν¨ν΄μ μμ£Ό μ€μν λΆλΆμ΄λ€.
μμ£Ό κ³ μ μ μΈ λ°©λ² (μνν λ°©λ²) public class Singleton { private static Singleton uniqueInstance; private Singleton(){} public static Singleton getInstance(){ if (uniqueInstance == null){ uniqueInstance = new Singleton(); } return uniqueInstance; } } μμ κ°μ μν©μμ ifμ μ λλ¬νλ μμ μ΄ κ° μ€λ λλ§λ€ λ€λ₯Όκ²½μ° λ¬Έμ κ° λ°μν μ μλ€.(κ΅λ¬ν μμ μ κ°μ²΄κ° 1κ° μ΄μ λ°νλ μ¬μ§κ° μμ) μ΄λ₯Ό ν΄κ²°νκΈ° μν΄μλ λ€μκ³Ό κ°μ΄ getInstance()λ₯Ό λκΈ°ν ν΄μ£Όλ©΄ λλ€. νμ§λ§ λΆνμνκ² λκΈ°ν νλ μ€λ²ν€λλ§ μ¦κ°νκ² λλ€.
public class Singleton { private static Singleton uniqueInstance; private Singleton(){} public static synchronized Singleton getInstance(){ if (uniqueInstance == null){ uniqueInstance = new Singleton(); } return uniqueInstance; } } public static μΈμ€ν΄μ€λ‘ μμ± public static final LocalCache sharedObject = new LocalCache(); private LocalCache() { } μ΄μ½λλ κ°λ¨νλ€λ μ₯μ μ΄ μλ λ°λ©΄μ μ μ°νμ§ λͺ»ν λΆλΆμ΄ μλ€. (μλ μ΄μ΄μ μ€λͺ
)
private static final μΈμ€ν΄μ€λ‘ μμ± private static final LocalCache sharedObject = new LocalCache(); private LocalCache() { } public static LocalCache getInstance() { return sharedObject ; } μ΄λ κ² νλ©΄ factory λ©μλλ₯Ό ν΅ν΄ κ°μ²΄λ₯Ό λ°νλ°κ³ , λ°ν λ°λ μμ μ λ€μν μμ
λ€μ ν μ μλ€.
enum μΌλ‘ μμ± public enum LocalCacheEnum { LocalCache; //etc another functions } μ μ¬μ©νμ§λ μμ§λ§ κ°μ₯ μ’μ μΈλ²μ§Έ λ°©λ²μΈ enumμΌλ‘ ν΄λμ€λ₯Ό λ§λλ λ°©λ²μ΄λΌκ³ νλ€. 볡μ‘ν μ§λ ¬νλ 리νλ μ
(reflection) μν©μμλ μ§λ ¬νκ° μλμΌλ‘ μ§μλκ³ , μΈμ€ν΄μ€κ° μ¬λ¬κ° μκΈ°μ§ μλλ‘ νμ€νκ² λ³΄μ₯ν΄μ€λ¨λ€. (by effective java)
κ·ΈλΌ μ΄λμ μ¬μ©λ κΉ static μΌλ‘ μ μΈν΄μ 곡ν΅μ μΌλ‘ μ¬μ©λλ λΆλΆμ΄λ νκ²½μ€μ λ΄μ©μ΄ λ³κ²½λλ©΄ λ€λ₯Έ ν΄λμ€μμλ κ·Έ λΆλΆμ΄ λκ°μ΄ μ μ©λμ΄ μ€νλμ΄μΌ ν λ μμ£Ό μ¬μ©λλ λΆλΆμ μ±κΈν€μΌλ‘ λ§λ€μ΄ μμ±λλ μκ°μ μ€μΌλ μ€νλ§μμμ DB컀λ₯μ
λ‘μ§
κ°μ μ΄μ ν¬μ€ν
μμ μ΄μΌκΈ° νκ²κ³Ό κ°μ΄ μ΄λκ³³μμλ μ§(μ§ λλ νμ¬ λ±) λΈλ‘κ·Έ ν¬μ€ν
μ ν μ μλ νκ²½μ λ§λ€κ³ μΆμλ€. (gitμ μ΄μ©ν΄μ.) κ·Έλμ git repository λ₯Ό λκ°λ₯Ό λ§λ€μκ³ , νλλ μ€μ λΈλ‘κ·Έμλ²λ‘ μ΄μ©νκ³ νλλ λΈλ‘κ·Έλ₯Ό ν¬μ€ν
νλ hexo νκ²½μ μ μ₯νκ² λλ€. μ§κΈλΆν° μ΄μΌκΈ° ν λ΄μ©μ hexoνκ²½μ git repository μμ pull λ°μμ ν경ꡬμ±νλ λΆλΆμ μ΄μΌκΈ° νλ €κ³ νλ€.
νκ²½κ΅¬μ± hexoμ€μΉμ gitμ€μΉλ λμ΄μλ€κ³ κ°μ . λ¨Όμ ꡬμ±ν ν΄λλ₯Ό μμ±νκ³ μ΄ ν΄λμ hexo νκ²½μ ꡬμ±νκ² λ€κ³ μ΄κΈ° μ
ν
μ νλ€
mkdir blog hexo init blog κ·Έλ¦¬κ³ hexoνκ²½μ μ μ₯ν΄λ repositoryλ₯Ό κ°μ ΈμμΌ νλ―λ‘ gitμ€μ μ νλ€
cd blog/ git init git remote add origin https://github.com/taetaetae/hexo.git git fetch νμμλμ΄κΈ°μ
ν
μ΄ λλ νμΌμ μ§μ°κ³
rm source/_posts/hello-world.md rm -r themes/landscape/ #ν΄λΉ ν
λ§λ₯Ό μ¬μ©νκ³ μλ€λ©΄ μ§μΈνμκ° μλ€. hexoνκ²½ repository λ₯Ό pullλ°λλ€
git reset --hard origin/master git pull origin master huemanν
λ§μ κ²μ κΈ°λ₯μ μ¬μ©νλ€λ κ°μ νμ νμν νλ¬κ·ΈμΈκ³Ό, λμ€μ deploy ν λ νμν νλ¬κ·ΈμΈμ μ€μΉν΄μ€λ€
npm install hexo-deployer-git --save npm install -S hexo-generator-json-content μ΄λ κ² λλ©΄ κΈ°μ‘΄μ²λΌ νκ²½μ€μ μ΄ λ§λ¬΄λ¦¬ λκ³ , ν¬μ€ν
μ ν μ μκ² λλ€.
μΆκ° canonical μμ± npm install –save hexo-auto-canonical μ¬μ΄νΈλ§΅ μμ± npm install hexo-generator-seo-friendly-sitemap –save feed μμ± npm install hexo-generator-feed –save