Spring 为什么要用到事务的准备?

版权声明:博客知识产权来源命运的信徒,切勿侵权 https://blog.csdn.net/qq_37591637/article/details/85207922

事务就是一个整个的过程,过程只有两个结果,成功和失败!

为什么用到事务呢?


以下是实例

需求:这个模拟一个书店的销售过程,当客户买走书以后,书的库存减少,而且客户的账户余额会减少

 书的编号   名称   价格

 书的编号    库存

 

 用户名  账户余额

 

总共涉及七个类,一个xml文件

 

首先是一个接口类

package cn.com.day04;

public interface BookShopDao {
     //根据书号获取书的单价
	public int findBookPriceByIsbn(String isbn);
	//更新书的库存,使得书号对应的库存-1
	public void updateBookStock(String isbn);
	//更新用户的账户余额,使得username的balance-price
	public void updateUserAccount(String username,int price);
}

实现类

package cn.com.day04;

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

@Repository
public class BookShopDaoImpl implements BookShopDao {
	@Autowired
	private JdbcTemplate jdbcTemplate = new JdbcTemplate();

	// 根据货号查询价格
	public int findBookPriceByIsbn(String isbn) {
		String sql = "select price from bookinfo where isbn=?";
		int price = jdbcTemplate.queryForObject(sql, Integer.class, isbn);
		return price;
	}

	// 根据货号更新库存
	public void updateBookStock(String isbn) {
		// 数据库没有约束,如果库存不足的话就需要手动的添加约束
		String sql0 = "select stock from bookstock where isbn=?";
		int stock = jdbcTemplate.queryForObject(sql0, Integer.class, isbn);
		if (stock == 0) {
			throw new BookStockException("库存不足....");

		}
		String sql = "update bookstock set stock=stock-1 where isbn=? ";
		jdbcTemplate.update(sql, isbn);
	}

	// 根据用户名和价格更新用户账户余额
	public void updateUserAccount(String username, int price) {
		// 数据库没有约束,如果库存不足的话就需要手动的添加约束
		String sql0 = "select count from usercount where username=?";
		int count = jdbcTemplate.queryForObject(sql0, Integer.class, username);
		if (count < price) {
			throw new BookCountException("余额不足....");
		}
		String sql1 = "update usercount set count=count-? where username=? ";
		jdbcTemplate.update(sql1, price, username);
	}

}

手动定义异常1

package cn.com.day04;

public class BookCountException extends RuntimeException {

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

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

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

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

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

}

手动定义异常2

package cn.com.day04;

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
	}

}

测试类

package cn.com.day04;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestFact {
	private static ApplicationContext ioc = null;
	private static BookShopDaoImpl bookShopDaoImpl = null;
	static {
		ioc = new ClassPathXmlApplicationContext("bean-jdbc.xml");
		bookShopDaoImpl = ioc.getBean(BookShopDaoImpl.class);

	}

	public void test1() {
		System.out.println(bookShopDaoImpl.findBookPriceByIsbn("1002"));
	}

	public void test2() {
		bookShopDaoImpl.updateBookStock("1001");
	}

	@Test
	public void test3() {
		bookShopDaoImpl.updateUserAccount("杨枫述", 28);
	}
}

到这里都是测试没有问题的!

但是买书,书的库存减少,账户余额减少,是一个整个过程,

于是乎

整合了一下代码

接口类

package cn.com.day04;

public interface BookShopService {
public void purchase(String username,String isbn);
}

实现类

package cn.com.day04;

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

@Service("bookShopService")
public class BookShopServiceImpl implements BookShopService{
	@Autowired
	private BookShopDaoImpl bookShopDaoImpl;
	@Override
	public void purchase(String username, String isbn) {
		//1.根据书的编号来查询价格
		int price=bookShopDaoImpl.findBookPriceByIsbn(isbn);
		//2.更新书的库存
		bookShopDaoImpl.updateBookStock(isbn);
		//2.根据用户名查询余额,扣除书的价格
		bookShopDaoImpl.updateUserAccount(username, price);
	}

}

在测试的时候,就发现一个问题,如果一个人的余额不够付这个书的价格的话,整个过程虽然会抛出我们刚才手动定义的异常

提示余额不足,但是书的库存还是减少了;

这个过程最后的结果明明没有交易成功,但是库存还是减少了!

这个就是我们需要用到事务的原因了

猜你喜欢

转载自blog.csdn.net/qq_37591637/article/details/85207922