版权声明:博客知识产权来源命运的信徒,切勿侵权 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);
}
}
在测试的时候,就发现一个问题,如果一个人的余额不够付这个书的价格的话,整个过程虽然会抛出我们刚才手动定义的异常
提示余额不足,但是书的库存还是减少了;
这个过程最后的结果明明没有交易成功,但是库存还是减少了!
这个就是我们需要用到事务的原因了