您的位置:首页 > 编程语言 > Java开发

[Spring]Spring AOP学习笔记(4)--Spring 事务

2015-09-24 17:50 489 查看
事务,具有原子性,通俗地说,就是要不都做,要不都不做。Spring作为一个框架,它也实现了原子这一点。这样,在做一些开发时,将省去很多事。以取钱为例,输出取款金额后,卡中余额减少,取款机出钞票。这3步应该是一致的,如果出现卡上余额减少,但是取款机没出钱的情况,估计银行的业务也就没人会使用了。

那么Spring是是如何实现事务的呢?以买书为例。分为三步。

Step 1: 查询价格;

Step 2:更新库存;

Step 3:更新购买者账号余额。

事务的实现,主要有2点,XML配置文件里,应该有这样的一段代码。

<!-- 配置事务管理器 -->
	<bean id="transactionManager" 
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	
	<!-- 启用事务注解 -->
	<tx:annotation-driven transaction-manager="transactionManager"/>


另外,事务上应该有这样的注释配置。

@Transactional
	@Override
	public void buy(int UserId, int id){
		System.out.println(bookdao);
		//1.查询价格
		int price = bookdao.findBookPriceById(id);
		
		//2.更新库存
		bookdao.updateBookStock(id);
		
		//3.更新用户余额
		bookdao.updateUserAccount(UserId, price);
	}


数据库设计如下:

数据库名:TransactionsTest

表名:Book,UserAccount





spring-adbc.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="com.spring.jdbc.test2"></context:component-scan>

<!-- 导入资源文件 -->
<context:property-placeholder location="classpath:db.properties" />

<!-- 配置c3p0数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${username}"></property>
<property name="password" value="${password}"></property>
<property name="jdbcUrl" value="${JdbcUrl}"></property>
<property name="driverClass" value="${driverClass}"></property>
<property name="numHelperThreads" value="10"></property>
<property name="initialPoolSize" value="${initPoolSize}"></property>
<property name="maxPoolSize" value="${maxPoolSize}"></property>
</bean>

<!-- 配置JDBCTemplate -->
<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>


db.properties

username=root
password=root
driverClass=com.mysql.jdbc.Driver
JdbcUrl=jdbc:mysql://127.0.0.1:3307/TransactionsTest

initPoolSize=5
maxPoolSize=10


package com.spring.jdbc.test2;

public interface BookDao {
		//根据书号获取书的单价
		public int findBookPriceById(int id);
		
		//更新数的库存. 使书号对应的库存 - 1
		public void updateBookStock(int id);
		
		//更新用户的账户余额
		public void updateUserAccount(int UserId, int price);

}


package com.spring.jdbc.test2;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

@Repository("bookDao")
public class BookDaoImpl implements BookDao {

	@Autowired
	private JdbcTemplate jdbcTemplate;

	@Override
	public int findBookPriceById(int id) {
		String sql = "select price from Book where id = ?";
		Integer num = jdbcTemplate.queryForObject(sql, Integer.class, id);
		return num;
	}

	@Override
	public void updateBookStock(int id) {
		String sql="select bookstock from Book where id=?";
		Integer bookstock = jdbcTemplate.queryForObject(sql, Integer.class, id);
		if(bookstock<1){
			throw new BookStockException("库存不足");
		}
		sql = "update Book set bookstock=bookstock-1 where id=?";
		jdbcTemplate.update(sql, id);
		return;
	}

	@Override
	public void updateUserAccount(int UserId, int price) {
		String sql="select Account from UserAccount where UserId=?";
		Integer account = jdbcTemplate.queryForObject(sql, Integer.class, UserId);
		if(account<price){
			throw new AccountException("余额不足");
		}
		sql = "update UserAccount set Account=Account-? where UserId=?";
		jdbcTemplate.update(sql, price, UserId);
		return;
	}

}


package com.spring.jdbc.test2;

public interface Buy {
	public void  buy(int UserId, int id);
}


package com.spring.jdbc.test2;

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

@Service("buyimpl")
public class BuyImpl implements Buy {

@Autowired
private BookDao bookdao;

@Transactional @Override public void buy(int UserId, int id){ System.out.println(bookdao); //1.查询价格 int price = bookdao.findBookPriceById(id); //2.更新库存 bookdao.updateBookStock(id); //3.更新用户余额 bookdao.updateUserAccount(UserId, price); }


}


package com.spring.jdbc.test2;

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.jdbc.test2;

public class AccountException extends RuntimeException{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

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

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

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

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

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

}


package com.spring.jdbc.test2;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
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 TestOne {
	private ApplicationContext ctx = new ClassPathXmlApplicationContext(
			"spring-jdbc.xml");
	BookDao bd = ctx.getBean(BookDaoImpl.class);
	Buy buy1 = (Buy) ctx.getBean("buyimpl");

	@Test
	public void testfindBookPriceById() {
		bd.findBookPriceById(1001);
		System.out.println(bd);
	}

	@Test
	public void testUpdateBookStock() {
		bd.updateBookStock(1001);
	}

	@Test
	public void testUpdateUserAccount() {
		bd.updateUserAccount(2011, 60);
	}

	@Test
	public void testBuy() {
		buy1.buy(2011, 1001);
	}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: