We programtically login users automatically to Magento 1.4.0.1; yes, I know it's old, we can't update because of core hacks by another developer.
Each user has the same password as we use our ERP to authenticate through a web service and then send the user's data to this function to log them into Magento to facilitate purchases.
We've been having a lot of SQL deadlock issues with the code shown below as Shortened Code.
This is the exception we've been logging, we can tell it's coming from the code below because that is the ONLY place anywhere in our system where Magento customer info is being updated:
[26-Aug-2015 18:56:12] PHP Fatal error: Uncaught exception 'Zend_Db_Statement_Exception' with message
'SQLSTATE[40001]: Serialization failure: 1213
Deadlock found when trying to get lock; try restarting transaction' in /store/lib/Zend/Db/Statement/Pdo.php:235
Stack trace:
#0 /store/lib/Zend/Db/Statement.php(300): Zend_Db_Statement_Pdo->_execute(Array)
#1 /store/lib/Zend/Db/Adapter/Abstract.php(468): Zend_Db_Statement->execute(Array)
#2 /store/lib/Zend/Db/Adapter/Pdo/Abstract.php(238): Zend_Db_Adapter_Abstract->query('UPDATE `magcust...', Array)
#3 /store/lib/Varien/Db/Adapter/Pdo/Mysql.php(333): Zend_Db_Adapter_Pdo_Abstract->query('UPDATE `magcust...', Array)
#4 /store/lib/Zend/Db/Adapter/Abstract.php(604): Varien_Db_Adapter_Pdo_Mysql->query('UPDATE `magcust...', Array)
#5 /store/app/code/core/Mage/Eav/Model/Entity/Abstract.php(1133): Zend_Db_Adapter_Abstract->update('magcustomer_ent...', Array, 'entity_id='9144...')
#6 /store/app in /srv/www/htdocs/store/lib/Zend/Db/Statement/Pdo.php on line 235
I tried using the changes to PDO.php here: http://www.kennguyen.me/magento-deadlock-error/
This caused more trouble than the deadlocks because for some reason our system began having Too many connections
errors after I implemented it. I took it back out and need some help determining if I can do something similar.
I thinking that adding the same technique that is used in the above post to our own code should alleviate the deadlocks and this is what I came up with.
SaveCustomer function
function SaveCustomer($customer) {
$max_tries = 3;
$tries = 0;
do {
$retry = false;
try {
$customer->save();
} catch (PDOException $e) {
if ($tries < $max_tries && preg_match('/SQLSTATE\[40001\]/', $e->getMessage())) {
$retry = true;
sleep(1);
} else {
throw new Zend_Db_Statement_Exception($e->getMessage(), (int)$e->getCode(), $e);
}
$tries++;
}
} while ($retry);
}
So all the $customer->save();
calls will now call SaveCustomer($customer);
Does the above function look like it will fix my problem???
Shortened Code:
function mag_login_or_create($ParticipantInfo, $UserData) {
//*****************************************************************
// This is a first time user registering and we pass $UserData
//*****************************************************************
if ($ParticipantInfo == false) {
$ret['error'] = '';
include_once MAGE_PATH;
Mage::app();
$customer = Mage::getModel('customer/customer');
$customer->setWebsiteId(Mage::app()->getWebsite()->getId());
$customer->loadByEmail($UserData['PrimaryEmail']);
if (!$customer->getId()) {
$customer->setEmail($UserData['PrimaryEmail']);
$customer->setFirstname($UserData['FirstName']);
$customer->setLastname($UserData['LastName']);
$customer->setPassword('password');
try {
$customer->save();
$ret['result'] = 'SUCCESS';
}
catch (Exception $e) {
$ret['result'] = 'FAILURE';
$ret['error'] .= $e->getMessage();
return $ret;
}
} else {
$customer->setFirstname($UserData['FirstName']);
$customer->setLastname($UserData['LastName']);
try {
$customer->save();
$ret['result'] = 'SUCCESS';
}
catch (Exception $e) {
$ret['result'] = 'FAILURE';
$ret['error'] .= $e->getMessage();
return $ret;
}
}
//*****************************************************************
// Now log the customer in using their email address
//*****************************************************************
Mage::getSingleton('core/session', array('name'=>'frontend'));
$session = Mage::getSingleton('customer/session');
$session->login($UserData['PrimaryEmail'],'********'); // password masked
if ($session->isLoggedIn()) {
$session->setCustomerAsLoggedIn($session->getCustomer());
$ret['result'] = 'SUCCESS';
} else {
$ret['result'] = 'FAILURE';
$ret['error'] .= 'login not established';;
}
return $ret;
} else {
//*****************************************************************
// This is a returning user so $ParticipantInfo is passed
//*****************************************************************
$ret['error'] = '';
include_once MAGE_PATH;
Mage::app();
$customer = Mage::getModel('customer/customer');
$customer->setWebsiteId(Mage::app()->getWebsite()->getId());
$customer->loadByEmail($ParticipantInfo['PrimaryEmail']);
if (!$customer->getId()) {
$customer->setEmail($ParticipantInfo['PrimaryEmail']);
$customer->setFirstname($ParticipantInfo['FirstName']);
$customer->setLastname($ParticipantInfo['LastName']);
$customer->setPassword('********'); // password masked
try {
$customer->save();
$ret['result'] = 'SUCCESS';
} catch (Exception $e) {
$ret['result'] = 'FAILURE';
$ret['error'] .= $e->getMessage();
return $ret;
}
} else {
$customer->setFirstname($ParticipantInfo['FirstName']);
$customer->setLastname($ParticipantInfo['LastName']);
try {
$customer->save();
$ret['result'] = 'SUCCESS';
} catch (Exception $e) {
$ret['result'] = 'FAILURE';
$ret['error'] .= $e->getMessage();
return $ret;
}
}
//*****************************************************************
// Here, we delete all their addresses so that we can "synchronize"
// them with what we have in our ERP.
//*****************************************************************
foreach ($customer->getAddresses() as $address) {
$address->delete();
}
//*****************************************************************
// The code here creates the new addresses, shortened
//*****************************************************************
$regionModel = Mage::getModel('directory/region')->loadByCode($ParticipantInfo['addstate'], $ParticipantInfo['addcountry']);
$regionId = $regionModel->getId();
$ParticipantInfoaddress = Mage::getModel("customer/address");
$ParticipantInfoaddress->setCustomerId($cid);
$ParticipantInfoaddress->firstname = $addfname;
$ParticipantInfoaddress->lastname = $addlname;
$ParticipantInfoaddress->prefix = $addpfix;
$ParticipantInfoaddress->country_id = $ParticipantInfo['addcountry'];
$ParticipantInfoaddress->postcode = $ParticipantInfo['addzip'];
$ParticipantInfoaddress->city = $ParticipantInfo['addcity'];
$ParticipantInfoaddress->region = $regionId;
$ParticipantInfoaddress->street = array('0'=>$ParticipantInfo['addstreet1'],'1'=>$ParticipantInfo['addstreet2'],'2'=>$ParticipantInfo['addstreet3']);
$ParticipantInfoaddress->setIsDefaultBilling('1');
$ParticipantInfoaddress->setIsDefaultShipping('1');
$ParticipantInfoaddress->setSaveInAddressBook('1');
$ParticipantInfoaddress->telephone = (array_key_exists('addphone', $ParticipantInfo)?$ParticipantInfo['addphone']:"---");
$ParticipantInfoaddress->save();
//*****************************************************************
// Now log the customer in using their email address
//*****************************************************************
Mage::getSingleton('core/session', array('name'=>'frontend'));
$session = Mage::getSingleton('customer/session');
$session->login($ParticipantInfo['PrimaryEmail'],'********'); // password masked
if ($session->isLoggedIn()) {
$session->setCustomerAsLoggedIn($session->getCustomer());
$ret['result'] = 'SUCCESS';
} else {
$ret['result'] = 'FAILURE';
$ret['error'] .= 'login not established';;
}
return $ret;
}
}