正常商城的商品是有库存的,预售商品意思是无库存概念;
正常存在库存:
无库存:
没有库存概念就会在购买的时候省掉减库存操作,就会省掉写数据库的操作,这会节省性能的,减小压力的;具体方法在如下:
public function registerProductsSale($items)
{
$qtys = $this->_prepareProductQtys($items);
$item = Mage::getModel('cataloginventory/stock_item');
$this->_getResource()->beginTransaction();
$stockInfo = $this->_getResource()->getProductsStock($this, array_keys($qtys), true);
$fullSaveItems = array();
foreach ($stockInfo as $itemInfo) {
$item->setData($itemInfo);
if (!$item->checkQty($qtys[$item->getProductId()])) {
$this->_getResource()->commit();
Mage::throwException(Mage::helper('cataloginventory')->__('Not all products are available in the requested quantity'));
}
$item->subtractQty($qtys[$item->getProductId()]);
if (!$item->verifyStock() || $item->verifyNotification()) {
$fullSaveItems[] = clone $item;
}
}
$this->_getResource()->correctItemsQty($this, $qtys, '-');
$this->_getResource()->commit();
return $fullSaveItems;
}
该方法里面用到了事务,调用了getProductsStock()方法;
public function getProductsStock($stock, $productIds, $lockRows = false)
{
if (empty($productIds)) {
return array();
}
$itemTable = $this->getTable('cataloginventory/stock_item');
$productTable = $this->getTable('catalog/product');
$select = $this->_getWriteAdapter()->select()
->from(array('si' => $itemTable))
->join(array('p' => $productTable), 'p.entity_id=si.product_id', array('type_id'))
->where('stock_id=?', $stock->getId())
->where('product_id IN(?)', $productIds)
->forUpdate($lockRows);
return $this->_getWriteAdapter()->fetchAll($select);
}
可以看到这里在getProductsStock()方法中还使用到了forUpdate()行锁。
maganto每次在执行的时候都会将所有的模块收集到一起然后统一便利,如果不将无用的模块关闭的话magento内部就会将所有的模块全部收集在一起这样对模块进行读取不但耗时而且还会增加压力,所以无用的模块果断关闭。
具体关闭无用模块点击看这篇文章
原因和关闭无用模块一样,而且配置的数量要比模块更多
可以走异步不需要同步操作或者是要使用到第三方的操作时使用队列。举例:用户邮箱注册给用户发确认邮件,这里邮件会使用的第三方,而且如果不拆分成异步的话会在用户注册时利用第三方发送确认邮件,用户需要等待而且第三方失败的话还会导致用户注册失败,所以这时候要使用异步队列,让用户先注册,邮件使用队列去发送,不但会减少压力而且还会减少失败操作的出现。
$this->_loadThemeTranslation($forceReload);
$this->_loadDbTranslation($forceReload);
magento在每个模块都有翻译模块,而且优先级模块自己的翻译模块要大于公共翻译模块,而且每个模块的翻译模块其实在我们使用的时候没什么必要,所以关闭就好了,把上面两句话注释掉就不会调用模块本身翻译模块。
在做项目的时候发现的一个问题,就是使用walle发布代码的时候每次发布完代码项目的缓存就会被重新生成,后来找了好久发现原来是magento的缓存位置有一段下面这行代码:
if (empty($this->_idPrefix)) {
$this->_idPrefix = substr(md5(Mage::getConfig()->getOptions()->getEtcDir()), 0, 3).'_';
}
而walle发布代码的时候使用软链接就会导致缓存的存放位置发生改变故而导致原缓存找不到所以重新生成新的缓存,解决方法,使用固定的位置:
if (empty($this->_idPrefix)) {
// $this->_idPrefix = substr(md5(Mage::getConfig()->getOptions()->getEtcDir()), 0, 3).'_';
$this->_idPrefix = '050_';
}
magento核心代码中对于用户下单是是否使用优惠券做相关处理,但是magento里面的处理逻辑是不管用户下单时候是否使用优惠券都会走相同的SQL,这样会导致影响下单的速度而且影响性能,所以要将一个SQL分成两个SQL,分为下单时使用优惠券和不使用优惠券;
magento原生代码如下:(app/code/core/Mage/SalesRule/Model/Validator.php)
public function init($websiteId, $customerGroupId, $couponCode)
{
$this->setWebsiteId($websiteId)
->setCustomerGroupId($customerGroupId)
->setCouponCode($couponCode);
$key = $websiteId . '_' . $customerGroupId . '_' . $couponCode;
if (!isset($this->_rules[$key])) {
$this->_rules[$key] = Mage::getResourceModel('salesrule/rule_collection')
->setValidationFilter($websiteId, $customerGroupId, $couponCode)
->load();
}
return $this;
}
拆分完之后如下:
public function init($websiteId, $customerGroupId, $couponCode)
{
$this->setWebsiteId($websiteId)
->setCustomerGroupId($customerGroupId)
->setCouponCode($couponCode);
$key = $websiteId . '_' . $customerGroupId . '_' . $couponCode;
if (!isset($this->_rules[$key])) {
if(!$couponCode){
$this->_rules[$key] = Mage::getResourceModel('salesrule/rule_collection')
->setValidationFilter($websiteId, $customerGroupId, $couponCode)
->load();
}else{
$rule_collection = Mage::getResourceModel('salesrule/rule_collection')
->setValidationFilter($websiteId, $customerGroupId, '');
$coupon_rule_collection = Mage::getResourceModel('salesrule/rule_collection')
->setCouponValidationFilter($websiteId, $customerGroupId, $couponCode);
$merged_ids = array_merge($rule_collection->getAllIds(), $coupon_rule_collection->getAllIds());
$this->_rules[$key] = Mage::getResourceModel('salesrule/rule_collection')
->addFieldToFilter('rule_id', array('in' => $merged_ids))
->setOrder('sort_order', 'ASC')
->load();
}
}
return $this;
}
(app/code/core/Mage/SalesRule/Model/Resource/Rule/collection.php)
public function setCouponValidationFilter($websiteId, $customerGroupId, $couponCode = '', $now = null)
{
if (!$this->getFlag('coupon_validation_filter')) {
/* We need to overwrite joinLeft if coupon is applied */
$this->getSelect()->reset();
parent::_initSelect();
$this->addWebsiteGroupDateFilter($websiteId, $customerGroupId, $now);
$select = $this->getSelect();
$connection = $this->getConnection();
if (strlen($couponCode)) {
$select->joinLeft(
array('rule_coupons' => $this->getTable('salesrule/coupon')),
$connection->quoteInto(
'main_table.rule_id = rule_coupons.rule_id AND main_table.coupon_type != ?',
Mage_SalesRule_Model_Rule::COUPON_TYPE_NO_COUPON
),
array('code')
);
$orWhereConditions = array(
$connection->quoteInto(
'(main_table.coupon_type = ? AND rule_coupons.type = 0)',
Mage_SalesRule_Model_Rule::COUPON_TYPE_AUTO
),
$connection->quoteInto(
'(main_table.coupon_type = ? AND main_table.use_auto_generation = 1 AND rule_coupons.type = 1)',
Mage_SalesRule_Model_Rule::COUPON_TYPE_SPECIFIC
),
$connection->quoteInto(
'(main_table.coupon_type = ? AND main_table.use_auto_generation = 0 AND rule_coupons.type = 0)',
Mage_SalesRule_Model_Rule::COUPON_TYPE_SPECIFIC
),
);
$orWhereCondition = implode(' OR ', $orWhereConditions);
$select->where(
'((' . $orWhereCondition . ') AND rule_coupons.code = ?)', $couponCode
);
}
$this->setOrder('sort_order', self::SORT_ORDER_ASC);
$this->setFlag('coupon_validation_filter', true);
}
return $this;
}