針對mysql和mongo的兩個小例子:java
mysql:mysql
import com.example.demo.mapper.OrderInfoMapper; import com.example.demo.mapper.ProductInfoMapper; import com.example.demo.model.OrderInfo; import com.example.demo.model.ProductInfo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.Date; import java.util.Random; import java.util.concurrent.TimeUnit; @Service public class OrderMysqlService { @Autowired private OrderInfoMapper orderInfoMapper; @Autowired private ProductInfoMapper productInfoMapper; //下單 public boolean insert(){ Long productId = 22l;//產品id int buyCount = 1;//當前用戶下單數量 if(updateProductAmount(productId,buyCount)){ // if(true){ // throw new RuntimeException(); // } OrderInfo orderInfo = new OrderInfo(); orderInfo.setStatus(1); orderInfo.setCreateTime(new Date()); return orderInfoMapper.insertSelective(orderInfo) > 0; } return false; } //秒殺服務,修改庫存 private boolean updateProductAmount(Long productId,int buyCount) { ProductInfo productInfo = productInfoMapper.selectByPrimaryKeyByBuyCount(productId,buyCount); if (productInfo == null) { return false; } if (productInfoMapper.updateByStock(productId, buyCount) > 0) { return true; } //若是更新失敗,當前線程休眠,錯峯執行(同時執行的話,仍是隻有一我的搶佔到資源,別的都失敗,因此錯峯執行) waitForLock(); return updateProductAmount(productId, buyCount); } private void waitForLock(){ try { TimeUnit.MILLISECONDS.sleep(new Random().nextInt(10) + 1); } catch (InterruptedException e) { e.printStackTrace(); } } }
mongo:副本集mongodb才能支持事物:4.0以後的版本才能支持事物
4.0支持事物的步驟搭建:https://blog.csdn.net/quanmaoluo5461/article/details/84880850
git
import com.example.demo.model.Order; import com.example.demo.model.Product; import com.mongodb.client.result.UpdateResult; import org.bson.types.ObjectId; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.Random; import java.util.concurrent.TimeUnit; @Service public class OrderMongoService { @Autowired private MongoTemplate mongoTemplate; //下單 : 副本集mongodb才能支持事物。意思就是至少兩個mongo服務。具體操做查看:https://blog.csdn.net/quanmaoluo5461/article/details/84880850 @Transactional public boolean insert(){ String productId = "5c23a6b4be592e584c8d7c47";//產品id int buyCount = 1;//當前用戶下單數量 if(updateProductAmount(productId,buyCount)){ // if(true){ // throw new RuntimeException(); // } Order order = new Order(); order.setStatus(1); return mongoTemplate.insert(order).getId() != null; } return false; } //秒殺服務,修改庫存 private boolean updateProductAmount(String productId,int buyCount) { Criteria criteria = Criteria.where("id").is(new ObjectId(productId)) .and("stock").gte(buyCount); Query query = new Query(criteria); Product product = mongoTemplate.findOne(query,Product.class); if (product == null) { return false; } Update update = new Update(); update.inc("stock", -buyCount); UpdateResult updateResult= mongoTemplate.updateFirst(query, update, Product.class); if(updateResult.getModifiedCount() > 0){ return true; } //若是更新失敗,當前線程休眠,錯峯執行(同時執行的話,仍是隻有一我的搶佔到資源,別的都失敗,因此錯峯執行) waitForLock(); return updateProductAmount(productId, buyCount); } private void waitForLock(){ try { TimeUnit.MILLISECONDS.sleep(new Random().nextInt(10) + 1); } catch (InterruptedException e) { e.printStackTrace(); } } }
源碼地址:https://github.com/qjm201000/seckill.gitgithub
說明:mysql的sql文件(concurrent.sql)放在項目跟目錄下;mongodb的數據庫文件純json字符串,未備份,數據結構和mysql同樣。spring