首页 > 学院 > 开发设计 > 正文

spring学习-4-事务

2019-11-06 07:50:30
字体:
来源:转载
供稿:网友

sPRing声明式事务:

编写接口

import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;@Service("BookShopService")public class BookShopServiceImpl implements BookShopService{		@Autowired	private BookShopDao bookShopDao;	//添加事务注解	@Transactional	@Override	public void purchase(String username, String isbn) {		//获取书的单价		int price=bookShopDao.findBookPriceByIsbn(isbn);		//更新书的库存		bookShopDao.updateBookStock(isbn);		//更新用户余额		bookShopDao.updateUserAccount(username, price);	}}
public interface BookShopDao {	//根据书号查询价格	public int findBookPriceByIsbn(String isbn);	//更新图书库存	public void updateBookStock(String isbn);	//更新用户余额	public void updateUserAccount(String username,int price);}

接口实现类

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 sql2="select stock from book_stock where isbn=?";		Integer 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) {		String sql2="select balance from account where username=?";		Integer 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 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	}}
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	}}

配置文件

<?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:aop="http://www.springframework.org/schema/aop"	xmlns:context="http://www.springframework.org/schema/context"	xmlns:tx="http://www.springframework.org/schema/tx"	xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">		<context:component-scan base-package="spring.transactionmanager"></context:component-scan>	<!-- 加载配置文件 -->	<context:property-placeholder location="classpath:db.properties" />	<!-- 数据库连接池 -->	<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"		destroy-method="close">		<property name="url" value="${jdbc.url}" />		<property name="username" value="${jdbc.username}" />		<property name="passWord" value="${jdbc.password}" />		<property name="driverClassName" value="${jdbc.driver}" />		<property name="maxActive" value="10" />		<property name="minIdle" value="5" />	</bean>	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">		<property name="dataSource" ref="dataSource"></property>	</bean>	<!-- 配置事务管理器 -->	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">		<property name="dataSource" ref="dataSource"></property>	</bean>	<!-- 启用事务注解 -->	<tx:annotation-driven transaction-manager="transactionManager"/></beans>测试类

import static org.junit.Assert.*;import org.junit.Test;import org.springframework.context.applicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class SpringTransactionTest {	ApplicationContext ctx=null;	BookShopDao bookShopDao=null;	BookShopService bookShopService=null;	{		ctx=new ClassPathXmlApplicationContext("applicationContext.xml");		bookShopDao=ctx.getBean(BookShopDao.class);		bookShopService=ctx.getBean(BookShopService.class);	}	@Test	public void testBookShopService(){		bookShopService.purchase("AA", "1001");	}	@Test	public void testFindBookPriceByIsbn(){		System.out.println(bookShopDao.findBookPriceByIsbn("1001"));	}	@Test	public void testUpdateBookStock(){		bookShopDao.updateBookStock("1001");	}	@Test	public void testUpdateUserAccount(){		bookShopDao.updateUserAccount("AA", 100);	}}

事务的传播行为:

当事务方法被另一个事务方法调用时,必须指明事务方法该如何传播

@Service("bookShopService")public class BookShopServiceImpl implements BookShopService{		@Autowired	private BookShopDao bookShopDao;	//添加事务注解	/*	 * 使用propagation制定事务的传播行为,即当前事务方法被另外一个事务方法调用时,如何使用事务,默认取值为REQUIRED,即使用调用方法的事务		 * REQUIRES_NEW表示该方法必须启动一个新事务,并在一个自己的事务内运行,如果有事务在运行,就因该先挂起它	 * */	@Transactional(propagation=Propagation.REQUIRES_NEW)	@Override	public void purchase(String username, String isbn) {		//获取书的单价		int price=bookShopDao.findBookPriceByIsbn(isbn);		//更新书的库存		bookShopDao.updateBookStock(isbn);		//更新用户余额		bookShopDao.updateUserAccount(username, price);	}}购买多本书:

import java.util.List;public interface Casher {	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;@Service("casher")public class CasherImpl implements Casher{	@Autowired	private BookShopService bookShopService;		@Transactional	@Override	public void checkout(String username, List<String> isbns) {		for (String isbn : isbns) {			bookShopService.purchase(username, isbn);		}	}}
import static org.junit.Assert.*;import java.util.Arrays;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class SpringTransactionTest {    ApplicationContext ctx=null;    BookShopDao bookShopDao=null;    BookShopService bookShopService=null;    private Casher casher=null;    {        ctx=new ClassPathXmlApplicationContext("applicationContext.xml");        bookShopDao=ctx.getBean(BookShopDao.class);        bookShopService=ctx.getBean(BookShopService.class);        casher=(Casher) ctx.getBean("casher");    }    @Test    public void testTransactionPropagation(){        casher.checkout("AA", Arrays.asList("1001","1002"));    }}


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表