2017-12-04 30 views
1

JDBC 데이터베이스 액세스 API (기본적으로 래퍼)를 구현 중이며 과 PlatformTransactionManager이라는 스프링을 사용하여 트랜잭션 작업을 처리하고 있습니다. 모든게 괜찮아 보이지만 jdbcTemplate이 동시 트랜잭션을 관리하는 방법을 이해할 수 없습니다. 학생들의 창작을 토대로 간단한 예를 들어 설명하겠습니다. 2 명의 학생, John과 Jack을 만들어 보겠습니다. 첫 번째 오류가없는 초와 한 번의 오류가있는 초, 아래 단계와 코드가 있습니다.Spring PlatformTransactionManager - 동시 트랜잭션

  • 요한은 트랜잭션을 시작
  • 요한이없이 삽입 잭에 대한
  • 기다립니다 잭이
  • 잭 오류 (null를 세 만 데이터베이스에 필요한 비에 삽입 실행합니다 트랜잭션을 시작
  • 삽입 커밋 실행 - NULL)
  • 롤백 잭 트랜잭션
  • 커밋 John trasaction

StudentDAO

public class StudentJDBCTemplate implements StudentDAO { 

    private DataSource dataSource; 
    private JdbcTemplate jdbcTemplateObject; 
    private PlatformTransactionManager transactionManager; 

    // constructor, getters and setters 

    public TransactionStatus startTransaction() throws TransactionException { 
     TransactionDefinition def = new DefaultTransactionDefinition(); 
     transactionManager.getTransaction(def); 
    } 

    public void commitTransaction(TransactionStatus status) throws TransactionException { 
     transactionManager.commit(status); 
    } 

    public void rollbackTransaction(TransactionStatus status) throws TransactionException { 
     transactionManager.rollback(status); 
    } 

    public void create(String name, Integer age){ 
     String SQL1 = "insert into Student (name, age) values (?, ?)"; 
     jdbcTemplateObject.update(SQL1, name, age); 
     return; 
    } 
} 

MainApp에게 JdbcTemplate 1 트랜잭션이 확인하지만 다른 아니라고 알고 어떻게

public class MainApp { 
    public static void main(String[] args){ 
     // setup db connection etc 

     StudentJDBCTemplate studentDao = new StudentJDBCTemplate(); 

     TransactionStatus txJohn = studentDao.startTransaction(); 
     TransactionStatus txJack = studentDao.startTransaction(); 

     studentDao.create("John", 20); 

     try { 
      studentDao.create("Jack", null); // **FORCE EXCEPTION** 
     } catch(Exception e){ 
      studentDao.rollback(txJack); 
     } 
     studentDao.commit(txJohn); 
    } 
} 

? 우리가 2 개의 트랜잭션을 생성 했음에도 불구하고 JdbcTemplate은 쿼리와 실행 및 업데이트 메소드가 TransactionStatus를 매개 변수로 요구하지 않기 때문에 Jack AND John 트랜잭션을 롤백합니다. 즉, Spring jdbcTemplate은 시간당 1 개의 트랜잭션만을 지원합니까?!

+0

트랜잭션은 스레드 기반이며 2 개의 스레드가 있으며 각 스레드마다 고유 한 상태가 있습니다. –

+0

예제를 업데이트했습니다. 확인하십시오. 이제 jdbcTemplate이 studentDao.create 호출에서 사용할 transsaction을 어떻게 알 수 있습니까? – rmpt

+1

샘플은 하나의 트랜잭션을 사용하지만 2는 사용하지 않습니다. 2. 'startTransaction'에 대한 두 번째 호출은 이미 진행중인 트랜잭션의 상태를 반환합니다. 디버그 로깅을 활성화하면 진행중인 트랜잭션에 참여하고 있음을 나타내는 디버그 메시지의 두 번째 시작 결과가 표시됩니다. 'REQUIRES_NEW'로 지정된 경우에만 새 트랜잭션을 시작합니다. 그렇지 않으면 단일 트랜잭션이 시작됩니다. 다중 스레드를 사용하는 경우에만 여러 트랜잭션을 가질 수 있습니다. –

답변

1

단일 트랜잭션의 모든 작업은 항상 단일 단위로 실행되므로 모두 커밋되거나 전혀 처리되지 않습니다.

John이 삽입 및 업데이트하는 트랜잭션을 시작하면 둘 다 (삽입 및 업데이트) 성공하거나 수행하지 않으며 잭이 시작한 트랜잭션의 영향을받지 않습니다.

동시 트랜잭션이 서로 간섭하는 방식은 격리 수준, 즉 트랜잭션이 다른 동시 트랜잭션에 의해 수정 된 데이터를 보는 방식으로 제어됩니다.

+0

하지만 jdbcTemplate이 John 또는 Jack 트랜잭션 내에 update (SQL1, name, age)를 알고 있음을 알 수 있습니까? – rmpt

+0

Jack과 John이 서로 다른 매개 변수를 사용하여 동일한 양식을 제출할 때 개념이 동일합니다. 서버는 별도의 스레드를 사용하여 각 요청을 제공합니다. –

+0

아직도 내 질문에 대답하지 않습니다. 예제를 업데이트했습니다. 확인하십시오. 이제 jdbcTemplate이 studentDao.create 호출에서 트랜잭션을 사용해야하는 방법을 알 수있는 단 하나의 스레드 만 있습니다. – rmpt