图书类接口
package com.spring.tx;
public interface BookShopDao {
/**
* 根据书号查找加个
* @param isbn
* @return
*/
public int findBookPriceByIsbn(String isbn);
/**
* 更新书的库存
* @param isbn
*/
public void updateBookStock(String isbn);
/**
* 更新账户
* @param username
* @param price
*/
public void updateUserAccount(String username,int price);
}
图书类实现类
package com.spring.tx;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
@Repository("bookShopDao")
public class BookShopDaoImpl implements BookShopDao{
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public int findBookPriceByIsbn(String isbn) {
String sql ="SELECT price FROM book WHERE isbn = ?";
return jdbcTemplate.queryForObject(sql, Integer.class,isbn);
}
@Override
public void updateBookStock(String isbn) {
// 检查库存是否足够
String sql = "SELECT stock FROM book_stock WHERE isbn = ?";
Integer queryForObject = jdbcTemplate.queryForObject(sql, Integer.class,isbn);
if(queryForObject <=0){
throw new BookStockException("库存不足");
}
String sql2 = "UPDATE book_stock SET stock = stock -1 WHERE isbn = ?";
jdbcTemplate.update(sql2, isbn);
}
@Override
public void updateUserAccount(String username, int price) {
// 验证余额是否够,若不足,抛出异常
String sql = "SELECT balance FROM account WHERE username = ?";
Integer balance = jdbcTemplate.queryForObject(sql,Integer.class, username);
if(balance<price){
throw new UserAccountException("余额不足");
}
String sql2="UPDATE account SET balance = balance - ? WHERE username = ?";
jdbcTemplate.update(sql2, price,username);
}
}
图书Service
package com.spring.tx;
public interface BookShopService {
public void purchase(String username,String isbn);
}
图书Service 实现类
package com.spring.tx;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@Service("bookShopService")
public class BookShopServiceImpl implements BookShopService {
@Autowired
private BookShopDao bookShopDao;
// 添加事务注解
/**
* propagation 事务的传播行为 ,即当前的事务方法被另一个事务方法调用时适合使用事务
* 默认值Propagation.REQUIRED 使用调用事务的方法(共用一个事务)
* REQUIRES_NEW 使用自己的事务,调用事务的方法的事务被挂起
* isolation 制事务的隔离级别,常用的取值为READ_COMMITTED
* rollbackFor/norollbackFor 默认情况下Spring的声明式事务对所有的运行时异常进行回滚
* readOnly 制定事务是否为只读
* timeout 制定强制回滚之前事务可以占用时间
*/
@Transactional(propagation=Propagation.REQUIRES_NEW,
isolation=Isolation.READ_COMMITTED,rollbackFor={UserAccountException.class}
,readOnly=true,timeout=1
)
@Override
public void purchase(String username, String isbn) {
// 获取单价
int price = bookShopDao.findBookPriceByIsbn(isbn);
// 更新库存
bookShopDao.updateBookStock(isbn);
// 更新账户
bookShopDao.updateUserAccount(username, price);
}
}
出账接口
package com.spring.tx;
import java.util.List;
public interface CashierService {
public void checkout(String username,List<String> ibsns);
}
出账实现类
package com.spring.tx;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service("cashierService")
public class CashierServiceimpl implements CashierService {
@Autowired
private BookShopService bookShopService;
@Transactional
@Override
public void checkout(String username, List<String> ibsns) {
for(String ibsn:ibsns){
bookShopService.purchase(username, ibsn);
}
}
}
异常处理类
package com.spring.tx;
public class BookStockException extends RuntimeException{
/**
*
*/
private static final long serialVersionUID = 1L;
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
}
}
package com.spring.tx;
public class UserAccountException extends RuntimeException{
/**
*
*/
private static final long serialVersionUID = 1L;
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
}
}
Spring配置文件
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:tx="http://www.springframework.org/schema/tx" 6 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 7 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd 8 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> 9 10 <!-- 配置自动扫描的包 --> 11 <context:component-scan base-package="com.spring.tx"></context:component-scan> 12 <!-- 导入资源文件 --> 13 <context:property-placeholder location="classpath:db.properties" /> 14 15 <!-- 配置C3P0数据源 --> 16 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> 17 <property name="user" value="${jdbc.user}"></property> 18 <property name="password" value="${jdbc.password}"></property> 19 <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property> 20 <property name="driverClass" value="${jdbc.driverClass}"></property> 21 22 <property name="initialPoolSize" value="${jdbc.initPoorSize}"></property> 23 <property name="maxPoolSize" value="${jdbc.maxPoorSize}"></property> 24 </bean> 25 26 <!-- 配置Spring的JdbcTemplate --> 27 <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> 28 <property name="dataSource" ref="dataSource"></property> 29 </bean> 30 31 <!-- 配置事务管理器 --> 32 <bean id="transactionManager" 33 class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 34 <property name="dataSource" ref="dataSource"></property> 35 </bean> 36 37 <!-- 启用事物注解 --> 38 <tx:annotation-driven transaction-manager="transactionManager"/> 39 40 </beans>
数据源
1 jdbc.user=root 2 jdbc.password=123456 3 jdbc.driverClass=com.mysql.jdbc.Driver 4 jdbc.jdbcUrl=jdbc:mysql:///spring 5 6 jdbc.initPoorSize=5 7 jdbc.maxPoorSize=10
测试类
package com.spring.junit;
import java.sql.SQLException;
import java.util.Arrays;
import javax.sql.DataSource;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import com.spring.tx.BookShopDao;
import com.spring.tx.BookShopService;
import com.spring.tx.CashierService;
public class JdbcTest {
private ApplicationContext ctx =null;
private JdbcTemplate jdbcTemplate;
private BookShopDao bookShopDao =null;
private BookShopService bookShopService=null;
private CashierService cashierService = null;
{
ctx =new ClassPathXmlApplicationContext("applicationContext.xml");
jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate");
bookShopDao = ctx.getBean(BookShopDao.class);
bookShopService =ctx.getBean(BookShopService.class);
cashierService =ctx.getBean(CashierService.class);
}
/**
* 测试数据库连接
* @throws SQLException
*/
@Test
public void testJdbcTest() throws SQLException {
DataSource dataSource = ctx.getBean(DataSource.class);
System.out.println(dataSource.getConnection());
}
/**
* 执行insert delete update
*/
@Test
public void testJdbcTemplate(){
String sql = "update test1 set name = ? where id = ?";
jdbcTemplate.update(sql, "213","1");
}
/**
* 测试booksdao
*/
@Test
public void testBooksShopDao(){
int findBookPriceByIsbn = bookShopDao.findBookPriceByIsbn("1001");
bookShopDao.updateBookStock("1001");
bookShopDao.updateUserAccount("1", 100);
System.out.println(findBookPriceByIsbn);
}
/**
* 测试booksService
*/
@Test
public void testBookShopService(){
bookShopService.purchase("1", "1001");
}
/**
* 测试CashierService
*/
@Test
public void testCashierService(){
cashierService.checkout("1", Arrays.asList("1002","1001"));
}
}
Jar包
c3p0-0.9.1.2.jar
com.springsource.net.sf.cglib-2.2.0.jar
com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
commons-logging-1.1.3.jar
mysql-connector-java-5.1.7-bin.jar
spring-aop-4.0.0.RELEASE.jar
spring-aspects-4.0.0.RELEASE.jar
spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar
spring-jdbc-4.0.0.RELEASE.jar
spring-orm-4.0.0.RELEASE.jar
spring-tx-4.0.0.RELEASE.jar
spring-web-4.0.0.RELEASE.jar
spring-webmvc-4.0.0.RELEASE.jar