Java의 MyBatis 프레임워크에서의 트랜잭션 처리 상세 정보
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;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
MyBatis + SpringBoot로 CRUD 앱 만들기 ※ 불필요한 것은 배 ※ 1/2MyBatis를 사용하여 ToDo 목록을 만듭니다. 할 일 등록 (블랭크를 등록 할 수 없음) 할 일보기 할 일 변경 할 일 지우기 SpringBoot의 CRUD가 가능한 책은 있지만 MyBatis를 사용한 것은 적...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.