Scheduler transaction improvement and preferences transaction removal

* Added a transaction to createAndFillShowInstancesPastPopulatedUntilDate
  to ensure two requests don't trigger duplicate repeated show instances
  in the calendar.
* Removed the transaction from setValue() in Preference and opt for
  a row-level lock instead.
This commit is contained in:
Albert Santoni 2015-09-02 10:40:38 -04:00
parent c7d926f8e8
commit 6959c459cd
2 changed files with 25 additions and 12 deletions

View file

@ -28,7 +28,9 @@ class Application_Model_Preference
{ {
$cache = new Cache(); $cache = new Cache();
$con = Propel::getConnection(CcPrefPeer::DATABASE_NAME); $con = Propel::getConnection(CcPrefPeer::DATABASE_NAME);
$con->beginTransaction();
//We are using row-level locking in Postgres via "FOR UPDATE" instead of a transaction here
//because sometimes this function needs to be called while a transaction is already started.
try { try {
/* Comment this out while we reevaluate it in favor of a unique constraint /* Comment this out while we reevaluate it in favor of a unique constraint
@ -40,7 +42,7 @@ class Application_Model_Preference
} }
//Check if key already exists //Check if key already exists
$sql = "SELECT COUNT(*) FROM cc_pref" $sql = "SELECT valstr FROM cc_pref"
." WHERE keystr = :key"; ." WHERE keystr = :key";
$paramMap = array(); $paramMap = array();
@ -50,13 +52,16 @@ class Application_Model_Preference
if ($isUserValue) { if ($isUserValue) {
$sql .= " AND subjid = :id"; $sql .= " AND subjid = :id";
$paramMap[':id'] = $userId; $paramMap[':id'] = $userId;
} }
$sql .= " FOR UPDATE";
$result = Application_Common_Database::prepareAndExecute($sql, $result = Application_Common_Database::prepareAndExecute($sql,
$paramMap, $paramMap,
Application_Common_Database::COLUMN, Application_Common_Database::COLUMN,
PDO::FETCH_ASSOC, PDO::FETCH_ASSOC,
$con); $con);
$result = count($result);
$paramMap = array(); $paramMap = array();
if ($result > 1) { if ($result > 1) {
@ -103,9 +108,7 @@ class Application_Model_Preference
PDO::FETCH_ASSOC, PDO::FETCH_ASSOC,
$con); $con);
$con->commit();
} catch (Exception $e) { } catch (Exception $e) {
$con->rollback();
header('HTTP/1.0 503 Service Unavailable'); header('HTTP/1.0 503 Service Unavailable');
Logging::info("Database error: ".$e->getMessage()); Logging::info("Database error: ".$e->getMessage());
exit; exit;

View file

@ -847,14 +847,24 @@ SQL;
*/ */
public static function createAndFillShowInstancesPastPopulatedUntilDate($needScheduleUntil) public static function createAndFillShowInstancesPastPopulatedUntilDate($needScheduleUntil)
{ {
//UTC DateTime object $con = Propel::getConnection(CcPrefPeer::DATABASE_NAME);
$showsPopUntil = Application_Model_Preference::GetShowsPopulatedUntil(); try {
//if application is requesting shows past our previous populated until date, generate shows up until this point. $con->beginTransaction();
if (is_null($showsPopUntil) || $showsPopUntil->getTimestamp() < $needScheduleUntil->getTimestamp()) {
$service_show = new Application_Service_ShowService(); //UTC DateTime object
$ccShow = $service_show->delegateInstanceCreation(null, $needScheduleUntil, true); $showsPopUntil = Application_Model_Preference::GetShowsPopulatedUntil();
Application_Model_Preference::SetShowsPopulatedUntil($needScheduleUntil); //if application is requesting shows past our previous populated until date, generate shows up until this point.
if (is_null($showsPopUntil) || $showsPopUntil->getTimestamp() < $needScheduleUntil->getTimestamp()) {
$service_show = new Application_Service_ShowService();
$ccShow = $service_show->delegateInstanceCreation(null, $needScheduleUntil, true);
Application_Model_Preference::SetShowsPopulatedUntil($needScheduleUntil);
}
$con->commit();
} catch (Exception $e) {
$con->rollBack();
throw $e;
} }
} }
/** /**