Spring—事务3(基于XML配置的方式配置事务)

1. 代码准备

事务2那篇博客的代码基础上进行修改,删除所有注解,并在一些类里面添加set()方法:

修改如下:

public interface BookShopDao {
	
	//根据书号获取书的单价
	public int findBookPriceByIsbn(String isbn);
	
	//更新书的库存,使书的库存-1
	public void updateBookStock(String isbn);
	
	//更新用户账户余额,使其减去price
	public void updateUserAccount(String username, int price);
}
import org.springframework.jdbc.core.JdbcTemplate;

public class BookShopDaoImpl implements BookShopDao {
	
	private JdbcTemplate jdbcTemplate;
	
	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}
	@Override
	public int findBookPriceByIsbn(String isbn) {
		// TODO Auto-generated method stub
		String sql = "SELECT price FROM book WHERE isbn = ?";
		return jdbcTemplate.queryForObject(sql, Integer.class, isbn);
	}

	@Override
	public void updateBookStock(String isbn) {
		// TODO Auto-generated method stub
		//检查书的库存是否足够,若不够则抛出异常
		String sql2 = "SELECT stock FROM book_stock WHERE isbn = ?";
		int stock = jdbcTemplate.queryForObject(sql2, Integer.class, isbn);
		if(stock == 0) {
			throw new BookStockException("库存不足");
		}
		
		String sql = "UPDATE book_stock SET stock = stock - 1 WHERE isbn = ?";
		jdbcTemplate.update(sql, isbn);
	}

	@Override
	public void updateUserAccount(String username, int price) {
		// TODO Auto-generated method stub
		//验证余额是否不够,若不足则抛出异常
		String sql2 = "SELECT balance FROM account WHERE username = ?";
		int balance = jdbcTemplate.queryForObject(sql2, Integer.class, username);
		if(balance < price) {
			throw new UserAccountException("余额不足");
		}
		String sql = "UPDATE account SET balance = balance - ? WHERE username = ?";
		jdbcTemplate.update(sql, price, username);
	}

}
public interface BookShopService {
	
	public void purchase(String username, String isbn);
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;


public class BookShopServiceImpl implements BookShopService{
	
	private BookShopDao bookShopDao;
	
	public void setBookShopDao(BookShopDao bookShopDao) {
		this.bookShopDao = bookShopDao;
	}
	@Override
	public void purchase(String username, String isbn) {
		// TODO Auto-generated method stub
		//1.获取书的单价
		int price = bookShopDao.findBookPriceByIsbn(isbn);
		
		//2.更新书的库存
		bookShopDao.updateBookStock(isbn);
		
		//3.更新用户余额
		bookShopDao.updateUserAccount(username, price);
	}

}

public class BookStockException extends RuntimeException{

	public BookStockException() {
		super();
		// TODO Auto-generated constructor stub
	}

	public BookStockException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
		super(message, cause, enableSuppression, writableStackTrace);
		// TODO Auto-generated constructor stub
	}

	public BookStockException(String message, Throwable cause) {
		super(message, cause);
		// TODO Auto-generated constructor stub
	}

	public BookStockException(String message) {
		super(message);
		// TODO Auto-generated constructor stub
	}

	public BookStockException(Throwable cause) {
		super(cause);
		// TODO Auto-generated constructor stub
	}
	
	
}
public class UserAccountException extends RuntimeException{

	public UserAccountException() {
		super();
		// TODO Auto-generated constructor stub
	}

	public UserAccountException(String message, Throwable cause, boolean enableSuppression,
			boolean writableStackTrace) {
		super(message, cause, enableSuppression, writableStackTrace);
		// TODO Auto-generated constructor stub
	}

	public UserAccountException(String message, Throwable cause) {
		super(message, cause);
		// TODO Auto-generated constructor stub
	}

	public UserAccountException(String message) {
		super(message);
		// TODO Auto-generated constructor stub
	}

	public UserAccountException(Throwable cause) {
		super(cause);
		// TODO Auto-generated constructor stub
	}

	
}
import java.util.List;

public interface Cashier {
	public void checkout(String username, List<String> isbns);
}
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

public class CashierImpl implements Cashier {
	
	
	private BookShopService bookShopService;
	public void setBookShopService(BookShopService bookShopService) {
		this.bookShopService = bookShopService;
	}
	public void checkout(String username, List<String> isbns) {
		// TODO Auto-generated method stub
		for(String isbn:isbns) {
			bookShopService.purchase(username, isbn);
		}
	}

}

新建applicationContext-tx-xml.xml文档:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">


	<context:component-scan base-package="tx"></context:component-scan>
	<!-- 导入资源文件 -->
	<context:property-placeholder location = "classpath:db.properties"/>
	
	<!-- 配置C3P0数据源 -->
	<bean id = "dataSource" class = "com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="user" value="${jdbc.user}"></property>
		<property name="password" value="${jdbc.password}"></property>
		<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
		<property name="driverClass" value="${jdbc.driverClass}"></property>
		<property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>
		<property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
	</bean>
	
	<!-- 配置Spring的JdbcTemplate -->
	<bean id = "jdbcTemplate" class = "org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	
	<!-- 配置bean -->
	<bean id = "bookShopDao" class = "tx.xml.BookShopDaoImpl">
		<property name="jdbcTemplate" ref = "jdbcTemplate"></property>
	</bean>
	
	<bean id = "bookShopService" class = "tx.xml.BookShopServiceImpl">
		<property name="bookShopDao" ref = "bookShopDao"></property>
	</bean>
	
	<bean id = "cashier" class = "tx.xml.CashierImpl">
		<property name="bookShopService" ref = "bookShopService"></property>
	</bean>
</beans>

修改SpringTransactionTest测试运行:

import static org.hamcrest.CoreMatchers.nullValue;
import static org.junit.Assert.*;

import java.util.Arrays;

import org.junit.Test;
import org.omg.CORBA.PUBLIC_MEMBER;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringTransactionTest {
	  
	private ApplicationContext ctx = null;
	private BookShopDao bookShopDao = null;
	private BookShopService bookShopService = null;
	private Cashier cashier = null;
	{
		ctx = new ClassPathXmlApplicationContext("applicationContext-tx-xml.xml");
		bookShopDao = (BookShopDao) ctx.getBean("bookShopDao");
		bookShopService = (BookShopService) ctx.getBean("bookShopService");
		cashier = (Cashier) ctx.getBean("cashier");
	}
	
	@Test
	public void testBookShopService() {
		bookShopService.purchase("Tom", "1001");
	}
}

运行后,由于事务没有加上去,导致在余额不足的时候买书,库存还是会减1。

现在开始在xml中配置事务。配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">


	<context:component-scan base-package="tx.xml"></context:component-scan>
	<!-- 导入资源文件 -->
	<context:property-placeholder location = "classpath:db.properties"/>
	
	<!-- 配置C3P0数据源 -->
	<bean id = "dataSource" class = "com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="user" value="${jdbc.user}"></property>
		<property name="password" value="${jdbc.password}"></property>
		<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
		<property name="driverClass" value="${jdbc.driverClass}"></property>
		<property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>
		<property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
	</bean>
	
	<!-- 配置Spring的JdbcTemplate -->
	<bean id = "jdbcTemplate" class = "org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	
	<!-- 配置bean -->
	<bean id = "bookShopDao" class = "tx.xml.BookShopDaoImpl">
		<property name="jdbcTemplate" ref = "jdbcTemplate"></property>
	</bean>
	
	<bean id = "bookShopService" class = "tx.xml.BookShopServiceImpl">
		<property name="bookShopDao" ref = "bookShopDao"></property>
	</bean>
	
	
	<bean id = "cashier" class = "tx.xml.CashierImpl">
		<property name="bookShopService" ref = "bookShopService"></property>
	</bean>
	
	<!-- 1. 配置事务管理器 -->
	<bean id = "transactionManager" class = "org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	
	<!-- 2. 配置事务属性 -->
	<tx:advice id = "txAdvice" transaction-manager="transactionManager">
		<tx:attributes>
		<!-- 根据方法名指定事务的属性 -->
			<tx:method name="puchase" propagation="REQUIRES_NEW"/>
		</tx:attributes>
	</tx:advice>
	<!-- 3.配置事务切入点,以及把事务切入点和事务属性关联起来 -->
	<aop:config>
		<aop:pointcut expression="execution(* tx.xml.BookShopService.*(..))" 
		    id="txPointCut"/>
		<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
	</aop:config>
</beans>

仔细看看代码里的注释即可

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值