본문 바로가기

java,jsp,spring/Spring

Spring 트랜잭션

의미

- 논리적 단위로 어떤 한 부분의 작업이 완료되었다 해도, 다른 부분의 작업이 완료되지 않을 경우 전체 취소되는 것

  • 사용 방법 : platformTransactionManager를 이용
  • 필요한 설정
    • pom.xml
<!-- JDBC Template -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>4.1.4.RELEASE</version>
</dependency>
    • servlet-context.xml
<beans:bean name="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">        <beans:property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"></beans:property>     <beans:property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"></beans:property>
    <beans:property name="username" value="scott"></beans:property>
    <beans:property name="password" value="tiger"></beans:property>
</beans:bean>
<beans:bean name="template" class="org.springframework.jdbc.core.JdbcTemplate">
    <beans:property name="dataSource" ref="dataSource"/>
</beans:bean>
<beans:bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <beans:property name="dataSource" ref="dataSource" />
</beans:bean>
<beans:bean name="dao" class="com.javalec.spring_tran.dao.TicketDao" >
    <beans:property name="template" ref="template" />
    <beans:property name="transactionManager" ref="transactionManager" />
</beans:bean>
    • Dao
public class Dao {
	JdbcTemplate template;
	PlatformTransactionManager transactionManager;
	
	public void setTransactionManager(PlatformTransactionManager transactionManager) {
		this.transactionManager = transactionManager;
	}

	public void setTemplate(JdbcTemplate template) {
		this.template = template;
	}
	
	public void example(final Dto dto) {
		TransactionDefinition definition = new DefaultTransactionDefinition();
		TransactionStatus status = transactionManager.getTransaction(definition);
		
		try {
			template.update(new PreparedStatementCreator() {

			});
			transactionManager.commit(status);
		} catch (Exception e) {
			e.printStackTrace();
			transactionManager.rollback(status);
		}
	}
}

 

예제

  • 테이블 생성
CREATE TABLE CARD (consumerId VARCHAR2(10) ,amount NUMBER(1) );
CREATE TABLE TICKET (consumerId VARCHAR2(10) ,countNum NUMBER(1) CHECK(countNum < 5) );
  • Controller
@Controller
public class HomeController {
	private TicketDao dao;
	
	@Autowired
	public void setDao(TicketDao dao) {
		this.dao = dao;
	}

  @RequestMapping("buy_ticket")
	public String buy_ticket() {
		return "buy_ticket";
	}
	@RequestMapping("buy_ticket_card")
	public String buy_ticket_card(TicketDto ticketDto, Model model) {
		dao.buyTicket(ticketDto);
		model.addAttribute("ticketInfo", ticketDto);
		
		return "buy_ticket_end";
	}
}
  • Dao
public class TicketDao {
	JdbcTemplate template;
	PlatformTransactionManager transactionManager;
	
	public void setTransactionManager(PlatformTransactionManager transactionManager) {
		this.transactionManager = transactionManager;
	}

	public void setTemplate(JdbcTemplate template) {
		this.template = template;
	}
	
	public void buyTicket(final TicketDto dto) {
		TransactionDefinition definition = new DefaultTransactionDefinition();
		TransactionStatus status = transactionManager.getTransaction(definition);
		
		try {
			template.update(new PreparedStatementCreator() {
				@Override
				public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
					String query="INSERT INTO CARD(consumerId, amount) VALUES(?,?)";
					PreparedStatement pstmt = con.prepareStatement(query);
					pstmt.setString(1, dto.getConsumerId());
					pstmt.setInt(2, dto.getCountNum());
					return pstmt;
				}
			});
			
			template.update(new PreparedStatementCreator() {
				@Override
				public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
					String query="INSERT INTO TICKET(consumerId, countNum) VALUES(?,?)";
					PreparedStatement pstmt = con.prepareStatement(query);
					pstmt.setString(1, dto.getConsumerId());
					pstmt.setInt(2, dto.getCountNum());
					return pstmt;
				}
			});
			transactionManager.commit(status);
		} catch (Exception e) {
			e.printStackTrace();
			
			transactionManager.rollback(status);
		}
	}
}
  • Dto
public class TicketDto {
	private String consumerId;
	private int countNum;
	
	public String getConsumerId() {
		return consumerId;
	}
	public void setConsumerId(String consumerId) {
		this.consumerId = consumerId;
	}
	public int getCountNum() {
		return countNum;
	}
	public void setCountNum(int countNum) {
		this.countNum = countNum;
	}
}
  • jsp
// buy_ticket.jsp
<body>
	<p>카드 결제</p>
	<form action="buy_ticket_card" method="post">
		고객 아이디 : <input type="text" name="consumerId" /><br />
		티켓 구매수 : <input type="number" name="countNum" /><br />
		<input type="submit" value="구매" />
	</form>
</body>

//buy_ticket_end.jsp
<body>
	구매자 아이디 : ${ticketInfo.consumerId}<br />
	구매 수량 : ${ticketInfo.countNum}
</body>
// 5개 이상 구매 시 화면에 출력은 되지만 실제 DB에는 롤백되어 추가되어 있지 않음

'java,jsp,spring > Spring' 카테고리의 다른 글

Spring security  (0) 2022.10.19
Spring 프레임워크 표준형  (0) 2022.10.17
Spring MyBatis로 전환  (0) 2022.10.14
MyBatis  (0) 2022.10.14
Spring Jdbc Template  (0) 2022.10.14