본문 바로가기

코딩 학원(국비지원)

67일차 코딩학원

반응형

  코딩학원 공부 내용정리


1. 어제는 유효성 검증에 대해 공부했다. 오늘은 '트랜잭션'에 대해 공부한다. 

 

2. 트랜잭션 : 프로그램에서 어떤 이벤트가 발생했을 때 하나의 테이블에만 데이터를 변경하는 경우보다 여러 테이블을 차례로 변경해야 하는 경우가 많이 발생한다. 

 

예를들어 은행에서 계좌이체를 한다. 신한 은행 A계좌에서 B계좌로 이체한다고 했을 때 게좌는 테이블로 볼 수 있다. A계좌에서 100만 원을 차감하고 B계좌에 100만원을 추가하면 계좌이체가 완료된다. 만약 이 과정에서 에러가 발생하면 A계좌에서 차감했던 금액은 다시원래대로 되돌려야 한다. 

 

트랜잭션은 하나의 논리적 기능을 수행하기 위해 여러 작업을 묶어서 처리하는 것을 의미한다. commit, rollback등의 명령이 있다. 처리 과정에서 에러가 발생하면 rollback된다는 사실...! 

 

3. 명령어로 테이블을 만들고, 데이터베이스를 입력했었다. 그냥 오른쪽 클릭, 선택으로 생성해줄 수도 있다. 

4. commit이라는 단어가 자주 보인다. github에서도 나오고, Postgresql에서도 나온다. 

 

5. SQL에서 창 2개를 띄워두고 트랜잭션을 시험해보고 있다. 한 데이터에서 데이터베이스를 입력하고 커밋하지 않았다. 다른 한개의 창에서 read uncommited를 설정하고 데이터를 확인했는데... 나오지 않는다.  분명 커밋되지 않은 내용을 읽는다고 설정했음에도 읽을 수가 없다. 무엇이 문제일까? 

 

6. 오토커밋은 롤백이 되지 않는다. false로 설정하면 rollback 가능하다. 

package com.earth.work;

import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import javax.sql.DataSource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/**/root-context.xml")
public class TransactionTest {
	
	@Autowired
	DataSource ds; 
	
	@Test
	public void transactionTest() throws SQLException {
		Connection cn = null;
		
		try {
			deleteAll();
			cn = ds.getConnection();
			cn.setAutoCommit(false); //기본값은 cn.setAutoCommit(true)
			String sql = "INSERT INTO t_user VALUES (?,?,?,?,?,?,now())";
			PreparedStatement pstmt = cn.prepareStatement(sql);
			pstmt.setString(1, "earth1");
			pstmt.setString(2, "0629");
			pstmt.setString(3, "earth1");
			pstmt.setString(4, "earth1@gmail.com");
			pstmt.setDate(5, new Date(new java.util.Date().getTime()));
			pstmt.setString(6, "fb");
			
			int rowCnt = pstmt.executeUpdate(); //insert 실행함
			
			pstmt.setString(1, "earth1");
			rowCnt =  pstmt.executeUpdate();
			
			cn.commit();
			
		} catch (SQLException e) {
			e.printStackTrace();
			cn.rollback();
		}	
	}

	private void deleteAll() throws SQLException {
		Connection cn = ds.getConnection();
		String sql = "delete from t_user";
		PreparedStatement pstmt = cn.prepareStatement(sql);
		pstmt.executeUpdate();
	}
}

 

7. 관점 지향 프로그래밍 (AOP) 

스프링 프레임워크의 핵심 요소 중 하나다. 관심사의 분리를 허용함으로써 모듈성을 증가시킨다. 코드 자체를 수정하지 않는 대신 기존 코드에 추가 동작인 어드바이스를 정의하여 추가된 기능이 실행된다. 

 

8. 객체 주입이란 무엇인가? 객체가 필요로 하는 의존성을 외부에서 제공받는 것을 말한다. 클래스를 직접 생성하는 것이 아니라 클래스 외부에서 의존성을 생성하고 인자로 전달받아 객체를 조립한다. 객체 생성과 의존성 주입을 분리해서 코드의 재사용성과 유지보수성이 좋아졌다. 

 

9. 지금 뭘하고 있는걸까... AOP? 관심사를 분리한다는데... AOP에 대해서 따로 정리가 필요하다. 

package com.earth.work.app;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.springframework.transaction.annotation.Transactional;

class MyClass {
	@Transactional
	void ezen1() {					//@Transactional이 설정된 핵심기능 메서드에 부가기능을 추가 
		//부가 기능 (공통기능) before
		System.out.println("ezen1() 핵심기능 호출");	//핵심기능1
		//부가 기능 (공통기능) after	
	}
	void ezen2() {
		//부가 기능 (공통기능) 
		System.out.println("ezen2() 핵심기능 호출");	//핵심기능2
		//부가 기능 (공통기능)
	}
	void itezen1() {
		//부가 기능 (공통기능)
		System.out.println("ezen1() 핵심기능 호출");	//핵심기능3
		//부가 기능 (공통기능)
	}	
}

class MyAdvice {
	
	Pattern p = Pattern.compile("e.*");
	boolean matches(Method m) {
		//패턴에 맞는 것만 취해서 핵심기능에만 보조기능이 들어가게함
		Matcher matcher = p.matcher(m.getName());  
		return matcher.matches(); 
	}
	
	void invoke(Method m, Object obj, Object...args) throws Exception {
		if(m.getAnnotation(Transactional.class) != null) 
			System.out.println("[befor] {");
		m.invoke(obj, args);			//ezen1(), ezen2(), itezen1() 
		if(m.getAnnotation(Transactional.class) != null) 
			System.out.println("} [after]");
	}
}

public class AopMain {
	
	public static void main(String[] args) throws Exception {
		MyAdvice ma = new MyAdvice();
		Class myClass = Class.forName("com.earth.work.app.MyClass");
		Object obj = myClass.newInstance();
		
		for(Method m : myClass.getDeclaredMethods()) {
			ma.invoke(m, obj, null);
		}
	}
}

 

 

 

반응형

'코딩 학원(국비지원)' 카테고리의 다른 글

69일차 코딩학원  (0) 2023.04.27
68일차 코딩학원  (0) 2023.04.26
66일차 코딩학원  (0) 2023.04.24
65일차 코딩학원  (1) 2023.04.21
64일차 코딩학원  (2) 2023.04.20