3

So ,i am developing some extension for the company I work for on Magento (enterprise) and I was testing some code in an Observer going like this:

$_customer=Mage::getModel("customer/customer")->load($_order->getCustomerId());
$_customer->setData("blah_attribute","blah_value");
$_customer->save();
die();

And while I was calling $_customer->save() and that seemed like the correct way to save my customer object the data was never getting saved! So I dug into that save() function and down the road ended up realizing that this function was not actually saving but just building an array of things to update in the database. So I figured maybe it just builds all that big array of things to update (there seems to be also an array of things to insert, an array of things to delete and so on..) and at some point later it must go through those arrays and actually do it. I can understand how that can improve performance but that can also make testing pretty confusing! So anyways at some point I just removed the

die();

and suddenly my data was actually getting saved. (hours wasted! :/ )

I was wondering if anyone would be able to provide a little more insight on how that save() process actually works?

  • Which classes are called? When? By what processes?
  • How come it saves afterwards? At which point?
  • Can this sometimes cause problems?
  • Is there a way to force the save to happen right away?

1 Answer 1

3

My best guess is that you are hooking into an event that is working inside a transaction. In that case transaction has started at the beginning of the process and until it is committed no data are actually save into the database. Once you removed the die() the code reached commit call and you were able to see new data in the database.

[EDIT answering PVL comment]

Yes. In the code you've posted you get customer id from a variable called $_order. This suggest you are in a flow that manages an order. If this is placing the order then it is done within a transaction but creating a rma might not be. For example when you look at the placing order flow, ie. what happens when customer hits "Place order" button in checkout:

  1. After standard magento initialization and routing you end up in Mage_Checkout_OnepageController::saveOrderAction()
  2. There magento makes call $this->getOnepage()->saveOrder();
  3. saveOrder method creates a quote service object: $service = Mage::getModel('sales/service_quote', $this->getQuote()); and calls $service->submitAll();
  4. Inside Mage_Sales_Model_Service_Quote::submitAll() you go to submitOrder() method
  5. where a transaction object is created: $transaction = Mage::getModel('core/resource_transaction'); and both, quote and order are added to it
  6. Finally the save() method is called on the transaction model.
  7. If you look into Mage_Core_Model_Resource_Transaction::save() the first line starts transaction, then iterates over all objects added to the model, calling save() method on every one and if no exception is raised it commits the transaction, meaning allowing changes to be permanently stored to the database.
  8. But when something goes wrong and there is an exception, all changes are reverted so there would be no half data saved in the database.

You can see that if there is an error with placing the order you will not see any order data in the database even if the part of the code that saves new info works fine. Exception in payment processing that happens after saving basic order data in the table causes those data to be reverted. This way customer can change payment method and retry and you do not have your order table cluttered with failed orders attempts.

2
  • should I understand that sometimes you are in a transaction and sometimes not, and calling the same $customer->save() can either work immediately or not depending if you are in a transaction or not?
    – PVL
    May 25, 2016 at 18:54
  • Yes, as to how this happens check the edit in the answer
    – Zefiryn
    May 25, 2016 at 19:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.