redis-实现商品交易

一、结构设计

1、需要设计用户存储结构hash,来存放当前用户具有的金钱数
2、设计用户包裹set,里边存储了用户的所有商品
3、设计交易区market:zset集合来存储,存储格式为item.user price

用户流程:
1、将自己拥有的商品放置到贸易区,并设定一定的价格,在放置过程中需要去查看当前商品是否有变动,因为redis采用的是乐观锁
2、用户去交易区购买商品,首先去查看自身是否具有足够的钱去购买商品,一旦能够购买该商品,此时就去要需要修改购买者的钱数、修改出售者的钱数、交易区商品删除、购买者包裹添加该商品

二、用户挂卖商品

1、markets:表示交易区
2、inventory:表示自身包裹

// 查看商品列表
	public static boolean ListItem(Jedis jedis, String itemID, String sellerId, float price) {
		String inventory = "inventory:" + sellerId;
		String item = itemID + "." + sellerId;
		long end = System.currentTimeMillis() / 1000 + 5;
		while (System.currentTimeMillis() / 1000 < end) {
			jedis.watch(inventory);
			if (!jedis.sismember(inventory, itemID)) {
				jedis.unwatch();
				return false;
			}
			Transaction trans = jedis.multi();
			trans.zadd("markets:", price, item);
			trans.srem(inventory, itemID);
			List<Object> list = trans.exec();
			if (list == null) {
				continue;
			}
		}
		return true;
	}

三、购买商品

1、funds:hash结构中用户的钱数
2、商品在交易区结构:itemID .SellerID price

	public boolean purchase(Jedis jedis, String buyerID, String SellerID, String itemID) {
		String buyer = "user:" + buyerID;
		String seller = "user:" + SellerID;
		String item = itemID + "." + SellerID;
		String inventory = "inventory:" + buyerID;
		long time = System.currentTimeMillis() / 1000 + 10;
		while (System.currentTimeMillis() / 1000 < time) {
			jedis.watch(buyer);
			double buyerMoney = Double.parseDouble(jedis.hget(buyer, "funds"));
			double price = jedis.zscore("markets:", item);
			if (buyerMoney < price) {
				jedis.unwatch();
				return false;
			}
			Transaction trans = jedis.multi();
			trans.hincrBy(buyer, "funds", (int)-price);// 花钱
			trans.hincrBy(seller, "funds", (int)price);
			trans.sadd(inventory, itemID);// 添加商品
			trans.zrem("markets:", item);// 交易市场去掉该商品
			List<Object> list = trans.exec();
			if (list == null) {
				continue;
			}
			return true;
		}
		return false;
	}

四、test

private void testPurse(Jedis jedis) {
		jedis.hset("user:userY", "funds", "250");
		Map<String, String> map = jedis.hgetAll("user:userY");
		for (Map.Entry<String, String> entry : map.entrySet()) {
			System.out.println(entry.getKey() + ":" + entry.getValue());
		}
		assert map.size() > 0;
		boolean b = purchase(jedis, "userY", "userX", "ItemX");
		Set<String> set = jedis.smembers("inventory:userY");
		for (String temp : set) {
			System.out.println("购买商品:" + temp);
		}
		assert set.size() > 0;
		System.out.println("用户当前钱数");
		map = jedis.hgetAll("user:userY");
		for (Map.Entry<String, String> entry : map.entrySet()) {
			System.out.println(entry.getKey() + ":" + entry.getValue());
		}
		assert set.contains("ItemX");
		assert jedis.zscore("markets:", "itemX:userX") == null;

	}

	public void tesList(Jedis jedis) {
		String ItemID = "ItemX";
		String sellerID = "userX";
		System.out.println("添加商品");
		jedis.sadd("inventory:" + sellerID, ItemID);
		Set<String> set = jedis.smembers("inventory:" + sellerID);
		for (String temp : set) {
			System.out.println(temp);
		}
		assert set.size() > 0;
		System.out.println("将商品放置到交易区");
		ListItem(jedis, ItemID, sellerID, 10);
		Set<Tuple> tuples = jedis.zrangeWithScores("markets:", 0, -1);
		for (Tuple tuple : tuples) {
			System.out.println(tuple.getElement() + "-" + tuple.getScore());
		}
		assert tuples.size() > 0;
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值