天猫双十一有个积分换墨盒的活动,总共有50万台天猫魔盒(box),每个用户(user)可以用99个天猫积分(point)兑换一台魔盒,且每人限换一台。
请设计一套java接口并实现下单(order)逻辑。
0参考(但不局限于)下面的下单逻辑:
1、创建订单
2、扣减用户积分
3、扣减魔盒库存
4、下单成功
同时请回答:
1、数据库表结构如何设计,有哪些表,分别有什么作用?
2、下单过程中哪些地方可能成为瓶颈?如何解决或改善?
3、是否会用到数据库事务,哪些地方会用到?如果不用数据库事务,如何保证数据的一致性?
/**
* 用户类
* @author
*
*/
public class User {
private int id;
/**
* 用户积分
*/
private int credit;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getCredit() {
return credit;
}
public void setCredit(int credit) {
this.credit = credit;
}
}
public interface OrderOperation {
/**
* 创建订单
* @param user 用户
* @return 创建是否成功
*/
public boolean createOrder(User user);
/**
* 扣除用户积分
* @param user 用户
* @return 积分扣减是否成功
*/
public boolean minusCredit(User user);
/**
* 扣除天猫盒子
* @return 扣除是否成功
*/
public boolean minusBoxStock();
/**
* 下单
* @param user 下单的用户
* @return 下单是否成功
*/
public boolean OrderTemplet(User user);
}
/**
* 魔盒库存类
* @author
*
*/
public class BoxStock {
private volatile static BoxStock boxStock;
private int currentNumOfBox = 500000;
private BoxStock (){}
/**
* 获取BoxStock的实例
* @return BoxStock实例
*/
public static BoxStock getBoxStock() {
if (boxStock == null) {
synchronized (BoxStock.class) {
if (boxStock == null) {
boxStock = new BoxStock();
}
}
}
return boxStock;
}
/**
* 获取当前剩余的魔盒数
* @return 剩余的魔盒数
*/
public int getCurrentNumOfBox() {
return currentNumOfBox;
}
/**
* 设置魔盒数
* @param currentNumOfBox 新的魔盒数
*/
public void setCurrentNumOfBox(int currentNumOfBox) {
this.currentNumOfBox = currentNumOfBox;
}
}
public class OrderOperationImpl implements OrderOperation {
BoxStock stock = BoxStock.getBoxStock();
@Override
public boolean createOrder(User user) {
// TODO Auto-generated method stub
if(stock.getCurrentNumOfBox() > 0 && user.getCredit() >= 99) {
return true;
}
return false;
}
@Override
public boolean minusCredit(User user) {
if(user.getCredit() >= 99) {
user.setCredit(user.getCredit() - 99);
return true;
}
return false;
}
@Override
public boolean minusBoxStock() {
// TODO Auto-generated method stub
if(stock.getCurrentNumOfBox() > 0) {
stock.setCurrentNumOfBox(stock.getCurrentNumOfBox() - 1);
return true;
}
return false;
}
public boolean OrderTemplet(User user) {
if(this.createOrder(user)) {
if(this.minusCredit(user)) {
if(this.minusBoxStock()) {
return true;
}
}
}
return false;
}
}
public class test {
public static void main(String[] args) {
OrderOperation op = new OrderOperationImpl();
User user = new User();
if(op.OrderTemplet(user)) {
System.out.println("下单成功");
}
}
}
1、数据库表结构如何设计,有哪些表,分别有什么作用?
魔盒表:box,作用:存储魔盒数量及附属属性
用户表:user,作用:存储用户信息及天猫积分等用户属性
订单表:order,作用:关联用户及魔盒订单相关属性信息
2、下单过程中哪些地方可能成为瓶颈?如何解决或改善?
瓶颈主要会存在写数据库的过程中,例如:
(1)魔盒数量修改
(2)用户天猫积分修改
(3)用户兑换魔盒记录次数修改
改善方法:
(1)程序逻辑上。在程序设计过程中,合理安排下单关联的方法顺序,比如先查询用户是否兑换过魔盒。
(2)数据表设计上。尽量减少表的冗余,尤其是涉及数值敏感字段。
3、是否会用到数据库事务,哪些地方会用到?如果不用数据库事务,如何保证数据的一致性?
需要数据库事物。
事物主要会用在写数据库的过程中,例如:
(1)魔盒数量修改
(2)用户天猫积分修改
(3)用户兑换魔盒记录次数修改
用数据库事物是做安全的保证数据一致性的方法。
不用事务的话需要在代码中体现,代码必须确保逻辑正确。