Java의 MyBatis 프레임워크에서의 트랜잭션 처리 상세 정보

8646 단어 MyBatis사무
1. MyBatis를 단독으로 사용할 때 SqlSession을 사용하여 트랜잭션을 처리합니다.

public class MyBatisTxTest { 
 
  private static SqlSessionFactory sqlSessionFactory; 
  private static Reader reader; 
 
  @BeforeClass 
  public static void setUpBeforeClass() throws Exception { 
    try { 
      reader = Resources.getResourceAsReader("Configuration.xml"); 
      sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); 
    } finally { 
      if (reader != null) { 
        reader.close(); 
      } 
    } 
  } 
   
  @Test 
  public void updateUserTxTest() { 
    SqlSession session = sqlSessionFactory.openSession(false); //  ,  
     
    try { 
      IUserMapper mapper = session.getMapper(IUserMapper.class); 
      User user = new User(9, "Test transaction"); 
      int affectedCount = mapper.updateUser(user); //  commit  
      User user = new User(10, "Test transaction continuously"); 
      int affectedCount2 = mapper.updateUser(user2); //  commit  
      int i = 2 / 0; //   
      session.commit(); //  ,  
    } finally { 
      session.close(); //  ,  
    } 
  } 
} 

2. Spring과 통합된 Spring의 트랜잭션 관리:
MyBatis-Spring을 사용하는 주요 원인은 MyBatis가 Spring의 사무 관리에 참여할 수 있도록 하기 때문이다.MyBatis에 새로운 특정한 사무 관리자를 만드는 것이 아니라 MyBatis-Spring은 Spring에 존재하는 DataSourceTransaction Manager를 이용합니다.
DataSourceTransactionManager가 설정되면 Spring에서 일반적인 방법으로 업무를 설정할 수 있습니다. @Transactional 메모와 AOP 스타일의 구성은 모두 지원됩니다.트랜잭션 처리 중에 별도의 SqlSession 객체가 생성되고 사용됩니다.업무가 끝났을 때, 이 세션은 적당한 방식으로 제출하거나 굴러갈 것입니다.
트랜잭션이 생성되면 MyBatis-Spring은 트랜잭션을 투명하게 관리합니다.당신의 DAO나 서비스 클래스에서는 추가 코드가 필요하지 않습니다.
1. 표준 구성
Spring의 트랜잭션을 설정하려면 Spring의 XML 구성 파일에서 DataSourceTransactionManager 객체를 간단히 만듭니다.

<bean id="transactionManager" class="org.springframework.jdbc.datasource 
  .DataSourceTransactionManager"> 
  <property name="dataSource" ref="dataSource"/> 
</bean> 
지정한 DataSource는 일반적으로 Spring의 임의의 JDBC DataSource를 사용할 수 있습니다.여기에는 연결 풀과 JNDI 검색을 통한 DataSource가 포함됩니다.
사무 관리자를 위한 DataSource는 SqlSessionFactory Bean을 만드는 데 사용되는 것과 같은 데이터 원본이어야 합니다. 그렇지 않으면 사무 관리자가 작업을 할 수 없습니다.
 
2. 용기 관리 업무
만약 JEE 용기를 사용하고 스프링을 용기 관리 업무에 참여하게 하려면, 스프링은 JtaTransaction Manager나 용기가 지정한 하위 클래스를 사용해서 설정해야 합니다.이 작업의 가장 편리한 방법은 Spring의 사무 명칭 공간:

<tx:jta-transaction-manager/> 
이 설정에서 MyBatis는 컨테이너에서 트랜잭션을 관리하는 다른 Spring 트랜잭션 자원과 같습니다.Spring은 자동으로 존재하는 컨테이너 트랜잭션을 사용하여 SqlSession을 추가합니다.업무를 시작하지 않았거나 업무 설정을 기반으로 해야 한다면, 스프링은 새로운 용기 관리 업무를 열 것입니다.
Spring의 트랜잭션 관리 대신 컨테이너를 사용하여 트랜잭션을 관리하려면 SqlSessionFactory Bean을 설정하여 다른 임의의 Spring 트랜잭션 관리자가 아닌 기본적인 MyBatis의 ManagedTransactionFactory를 사용해야 합니다.

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> 
  <property name="dataSource" ref="dataSource"/> 
  <property name="transactionFactoryClass"> 
    <value>org.apache.ibatis.transaction.managed.ManagedTransactionFactory"/> 
  </property> 
</bean> 
 
3. 프로그래밍 사무 관리
MyBatis의 SqlSession은 프로그래밍식 업무를 처리할 수 있는 지정된 방법을 제공합니다.그러나 MyBatis-Spring을 사용할 때 bean은 Spring에서 관리하는 SqlSession이나 맵을 사용하여 주입합니다.그럼 스프링은 보통 일을 처리한다는 거야.Spring에서 관리하는 SqlSession에서 SqlSession을 호출할 수 없습니다.commit(),SqlSession.rollback() 또는 SqlSession.close () 메서드.이렇게 하면 Unsupported Operation Exception 이상이 발생합니다.주입된 맵을 사용할 때 그 방법에 접근할 수 없습니다.연결이 자동 제출로 설정되었든 안 되었든 SqlSession 데이터 방법의 실행이나 Spring 업무 외에 임의로 맵을 호출하는 방법은 자동으로 제출됩니다.다음은 프로그래밍 트랜잭션 예입니다.

DefaultTransactionDefinition def = new DefaultTransactionDefinition(); 
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); 
TransactionStatus status = txManager.getTransaction(def); 
try{ 
  userMapper.insertUser(user); 
}catch(MyException ex){ 
  throw ex; 
} 
txManager.commit(status); 

4.@Transactional 방식:
클래스 경로에서 beans-da-tx.xml 파일을 만들고 beans-da.xml(시리즈 5)을 바탕으로 사무 설정을 추가합니다.

<!--   --> 
<bean id="txManager" 
  class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
    <property name="dataSource" ref="dataSource" /> 
</bean> 
 
<!--  , @Transactional  --> 
<tx:annotation-driven transaction-manager="txManager" /> 
 
<bean id="userService" class="com.john.hbatis.service.UserService" /> 

서비스 클래스:

@Service("userService") 
public class UserService { 
 
  @Autowired 
  IUserMapper mapper; 
 
  public int batchUpdateUsersWhenException() { //   
    User user = new User(9, "Before exception"); 
    int affectedCount = mapper.updateUser(user); //   
    User user2 = new User(10, "After exception"); 
    int i = 1 / 0; //   
    int affectedCount2 = mapper.updateUser(user2); //   
    if (affectedCount == 1 && affectedCount2 == 1) { 
      return 1; 
    } 
    return 0; 
  } 
 
  @Transactional 
  public int txUpdateUsersWhenException() { //   
    User user = new User(9, "Before exception"); 
    int affectedCount = mapper.updateUser(user); //   
    User user2 = new User(10, "After exception"); 
    int i = 1 / 0; //  ,  
    int affectedCount2 = mapper.updateUser(user2); //   
    if (affectedCount == 1 && affectedCount2 == 1) { 
      return 1; 
    } 
    return 0; 
  } 
} 

테스트 클래스에 추가:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = { "classpath:beans-da-tx.xml" }) 
public class SpringIntegrateTxTest { 
 
  @Resource 
  UserService userService; 
 
  @Test 
  public void updateUsersExceptionTest() { 
    userService.batchUpdateUsersWhenException(); 
  } 
 
  @Test 
  public void txUpdateUsersExceptionTest() { 
    userService.txUpdateUsersWhenException(); 
  } 
} 

5. TransactionTemplate 방식
beans-da-tx.xml에 추가:

<bean id="txTemplate" class="org.springframework.transaction.support.TransactionTemplate"> 
  <constructor-arg type="org.springframework.transaction.PlatformTransactionManager" ref="transactionManager" /> 
</bean> 

UserService 클래스에 가입:

@Autowired(required = false) 
TransactionTemplate txTemplate; 
 
public int txUpdateUsersWhenExceptionViaTxTemplate() { 
  int retVal = txTemplate.execute(new TransactionCallback<Integer>() { 
 
    @Override 
    public Integer doInTransaction(TransactionStatus status) { //   
      User user = new User(9, "Before exception"); 
      int affectedCount = mapper.updateUser(user); //   
      User user2 = new User(10, "After exception"); 
      int i = 1 / 0; //   
      int affectedCount2 = mapper.updateUser(user2); //   
      if (affectedCount == 1 && affectedCount2 == 1) { 
        return 1; 
      } 
      return 0; 
    } 
     
  }); 
  return retVal; 
} 

SpringIntegrateTxTest 클래스에 추가:

@Test 
public void updateUsersWhenExceptionViaTxTemplateTest() { 
  userService.txUpdateUsersWhenExceptionViaTxTemplate(); //  
} 

참고: 내보내지 않고 Exception 또는 RuntimeException을 캐치할 수 없습니다.

@Transactional 
public int txUpdateUsersWhenExceptionAndCatch() { //  , , 。 
  try { 
    User user = new User(9, "Before exception"); 
    int affectedCount = mapper.updateUser(user); //   
    User user2 = new User(10, "After exception"); 
    int i = 1 / 0; //   
    int affectedCount2 = mapper.updateUser(user2); //   
    if (affectedCount == 1 && affectedCount2 == 1) { 
      return 1; 
    } 
  } catch (Exception e) { //   
    e.printStackTrace(); 
  } 
  return 0; 
} 

좋은 웹페이지 즐겨찾기