참고 : 스프링 3.x 트랜잭션

In proxy mode (which is the default), only external method calls coming in through the proxy are intercepted. This means that self-invocation, in effect, a method within the target object calling another method of the target object, will not lead to an actual transaction at runtime even if the invoked method is marked with @Transactional.



질문

////////////////////////////// 

//예제소스 

////////////////////////////// 

@Service("testService") 

public class TestServiceImpl extends AbstractServiceImpl implements TestService 

@Resource(name = "testDao") 

private TestDao testDao; 


@Transactional(propagation = Propagation.REQUIRES_NEW) 

@Override 

public void txTest() 

HashMap<String, String> data01 = new HashMap<String, String>(); 

data01.put("ID", "0000001"); 

data01.put("NAME", "스파이더맨"); 

testDao.createTest01(data01); 


@Transactional(propagation = Propagation.REQUIRES_NEW) 

@Override 

public void txTest1() 

HashMap<String, String> data02 = new HashMap<String, String>(); 

data02.put("ID", "0000002"); 

data02.put("NAME", "배트맨"); 

testDao.createTest01(data02); 


HashMap<String, String> data01 = new HashMap<String, String>(); 

data01.put("ID", "0000001"); 

data01.put("NAME", "스파이더맨"); 

testDao.createTest01(data01); 


@Transactional 

@Override 

public void txTest2() 

txTest(); 

txTest1(); 


# 현재 상황 

ID 는 등록하고자 하는 테이블의 KEY 로 중복 등록 하면 예외가 발생 합니다.


Controller 에서 txTest 와 txTest1 을 따로 호출 하면 스파이더맨만 등록이 되고 배트맨은 등록이 안되는 원하는 결과를 얻을 수 있습니다. 


Controller 에서 txTest2를 호출 하면 모두 등록이 안되고 있습니다. (호출한 두 메소드 전체에 걸쳐 트랜잭션 적용됨) 


txTest2 에서 @Transactional 을 제거 하고 호출 하면 스파이더맨과 배트맨이 모두 등록이 됩니다. (트랜잭션 적용 안됨) 


txTest2 의 @Transactional 을 @Transactional(propagation = Propagation.REQUIRES_NEW) 로 변경해 보았는데 호출한 두 메소드 전체에 걸쳐 트랜잭션이 적용 됩니다. 


# 질문 

Controller 에서 txTest2 메소드를 호출 하여 

txTest() 에서 등록 된 값은 commit 이 되고 

txTest1() 에서 등록 된 값은 rollback 이 되게 하고 싶습니다. 

(스파이더맨만 등록이 되고 배트맨은 등록이 안되는 원하는 결과) 

방법이 없나요?


답변

안녕하세요. 표준프레임워크센터입니다.


Transactional은 Proxy기반으로 동작하기 때문에 직접호출(자기 호출)은 Transaction이 적용되지 않습니다.


즉, txTest2메소드에서 txTest, txTest1을 직접 호출하는 방식으로는 두 메소드의 Transaction이 먹지 않습니다.


처음에 하셨던것처럼 Controller를 통해 txTest, txTest1을 호출하시거나


txTest, txTest1 메소드를 외부 클래스로 빼서(인터페이스 기반이어야합니다) txTest2에서 호출하는 방식으로 


Transaction을 적용하시기 바랍니다.


감사합니다.


이걸 몰라서 한참 헤메었다.

pom.xml

<plugin>

<groupId>org.apache.tomcat.maven</groupId>

<artifactId>tomcat6-maven-plugin</artifactId>

<version>2.2</version>

<configuration>

             <!-- http port -->

   <port>8090</port>

            <!-- Using a different context path -->

   <path>/</path>

</configuration>

</plugin>


기본 포트와 기본 컨텍스트 이름을 사용하지 않을 때 설정 한다.


출처 : 

http://stackoverflow.com/questions/18511774/how-to-configure-maven-tomcat-port-in-eclipse

http://mojo.codehaus.org/tomcat-maven-plugin/configuration.html

groupId

그룹, 회사, 팀, 조직 프로젝트 또는 다른 그룹을 나타내며, 관례상 그룹 식별자는 프로젝트를 생성한 조직의 도메인 명을 java의 패키지 명처럼 거꾸로 표기하는 것이다. 


artifactId

groupId의 하위에 존재하는 각각의 프로젝트를 표현하는 유일한 식별자 이다.


version 

프로젝트의 특정한 배포(release)를 나타낸다. 프로젝트가 릴리스되었을 때 확정된 버전이 부여되며, 이 버전을 바탕으로 구성된 식별자를 통하여 프로젝트의 특정 버전을 지칭할 수 있게 된다. 프로젝트의 개발이 계속 진행중이라면 SNAPSHOT과 같이 버전으로 표기된 특별한 식별자를 사용하여 프로젝트의 버전을 구분할 수 있다.


packaging

프로젝트의 형태는 기본적으로 jar이며, 프로젝트가 생산하는 패키지된 아티팩트로 결정된다. packaging 이 jar인 프로젝트는 JAR 아카이브를 생산하며, 패키징이 war인 프로젝트는 웹 애플리케이션을 생산한다.



출처 : Sonatype이 만든 Maven 핵심 가이드

property 파일을 CLASSPATH 에 넣고 ClassLoader.getSystemResource 를 사용해서 불러올 때

property 파일의 위치가 패키지 않에 있다면 package 명 까지 정확하게 적어줘야 한다.


당연한데 나만 몰랐나...


Properties prop = new Properties();


try

{

   prop.load(ClassLoader.getSystemResource("org/redgura/property/conifg.properties").openStream());

}

catch (IOException e)

{

   e.printStackTrace();

}


String time = prop.getProperty("TIME");



알간? 모르간?



http://superclassic.jp/?pid=41001

출처 : 시퀀스 현재값 변경하기(alter sequence startwith ???)


1. 시퀀스의 현재 값을 확인

SELECT LAST_NUMBER FROM USER_SEQUENCES WHERE SEQUENCE_NAME = 'TB_ZZTRACE_SQ01';


2. 시퀀스의 INCREMENT 를 현재 값만큼 빼도록 설정 (아래는 현재값이 999999 일 경우)

ALTER SEQUENCE TB_ZZTRACE_SQ01 INCREMENT BY -999999;


3. 시퀀스에서 다음 값을 가져 온다

SELECT TB_ZZTRACE_SQ01.NEXTVAL FROM DUAL;


4. 현재 값을 확인 해보면 -999999 만큼 증가 했다

SELECT TB_ZZTRACE_SQ01.CURRVAL FROM DUAL;


5. 시퀀스의 INCREMENT 를 1로 설정 한다

ALTER SEQUENCE TB_ZZTRACE_SQ01 INCREMENT BY 1;


6. 시퀀스가 1부터 다시 시작 한다.




같은 세션에서 시퀀스의 다음 값을 한번 조회한 다음에 사용하면 오류가 발생하지 않는다.


현재 값을 구하기 위해서는 맨 마지막으로 조회된 값을 조회 해도 된다.


SELECT LAST_NUMBER FROM USER_SEQUENCES WHERE SEQUENCE_NAME = 'TB_ZZTRACE_SQ01';


외부에서 내 컴퓨터(Host) 의 VM(Guest) 으로 접근하기 위하여 NAT 설정을 한다.




1. Virtual Machine Settings 에서 Network connection 을 NAT로 설정 한다.


2. Virtual Network Editor 에서 NAT Type 의 Network 을 선택하고 NAT Settings 버튼을 누른다.

Subnet IP 와 Subnet mask 를 확인 해둔다.



3. Add 버튼을 눌러서 Host 에서 Guest 에의 Port Forwarding 을 설정 한다.

NAT Settings 에서 Gateway IP 를 확인 해둔다.



4. Host 로 들어오는 TCP 8078 Port 에 대한 요청은 Guest 192.168.56.131 의 8078 Port 로 Forwarding 하라는 설정 이다.



5. 네트워크 연결에서 1번에서  NAT Type 의 Network 와 같은 이름을 가진 Network 를 선택하고 속성 TCP/IP v4 속성 으로 들어 간다.



6. 위와 같이 IP와 서브넷마스크를 설정 한다.



7. Guest 에서는 위와 같이 Network 를 설정 한다.

3번에서 확인한 Gateway IP 와 Subnet mask 를 적는다.


8. Guest 에서 8078 Port로 Socket Server 를 띄우고 외부에서 접근을 테스트 한다.

UDP 137 

UDP 138 

TCP 139 

TCP 445


+ Recent posts