cakephp2でリンクを叩いたらajax(php)が走るような処理を作っています。
このajaxの中でMysqlのトランザクションの処理があるのですがリンクを連打するとトランザクションが効かない時があって困っています。
トランザクションが100%効くことはありえないのでしょうか?
addとcancelを交互に実行しています。
php
1 public function add() 2 { 3 4 // 記事ID取得 5 $article_id = $this->_get_article_id(); 6 if (!$article_id) { 7 return; 8 } 9 10 // セッションID取得 11 $session_id = $this->_get_session_id(); 12 if (!$session_id) { 13 return; 14 } 15 16 // トランザクション開始 17 $this->model->begin(); 18 $query_log = $this->model->getDataSource()->getLog(); 19 $this->log('add-'.$query_log['log'][0]['query'],LOG_DEBUG); 20 21 // 既に同じ人で同じ記事IDで登録されていないかチェック 22 $count = $this->model->find('count', array( 23 'fields' => array('id'), 24 'conditions' => array( 25 'article_id' => $article_id, 26 'session' => $session_id, 27 ), 28 )); 29 $query_log = $this->model->getDataSource()->getLog(); 30 $this->log('add-1'.$query_log['log'][0]['query'],LOG_DEBUG); 31 32 if ($count >= 1) { 33 // ロールバック 34 $this->model->rollback(); 35 $query_log = $this->model->getDataSource()->getLog(); 36 $this->log('add-cnt(1):'.$query_log['log'][0]['query'],LOG_DEBUG); 37 $this->_error('failed added article_id'); 38 return; 39 } 40 41 // save用配列作成 42 $data['action_datetime'] = date('Y/m/d H:i:s'); 43 $data['article_id'] = $article_id; 44 $data['session'] = $session_id; 45 $data['ip_address'] = env('REMOTE_ADDR'); 46 $data['user_agent'] = env('HTTP_USER_AGENT'); 47 48 // データ保存 49 if ($this->model->save($data)) { 50 $this->log("add article_id: $article_id", 'article_useful'); 51 $query_log = $this->model->getDataSource()->getLog(); 52 $this->log('add-2'.$query_log['log'][0]['query'],LOG_DEBUG); 53 54 // コミット 55 $this->model->commit(); 56 $query_log = $this->model->getDataSource()->getLog(); 57 $this->log('add-3'.$query_log['log'][0]['query'],LOG_DEBUG); 58 59 } else { 60 $query_log = $this->model->getDataSource()->getLog(); 61 $this->log('add-4'.$query_log['log'][0]['query'],LOG_DEBUG); 62 // ロールバック 63 $this->model->rollback(); 64 $query_log = $this->model->getDataSource()->getLog(); 65 $this->log('add-5'.$query_log['log'][0]['query'],LOG_DEBUG); 66 debug('save failed'); 67 exit; 68 } 69 70 $this->set('result', true); 71 $this->set('message', "add ok"); 72 $this->set('_serialize', array('result', 'message')); 73 74 } 75 public function cancel() 76 { 77 78 // 記事ID取得 79 $article_id = $this->_get_article_id(); 80 if (!$article_id) { 81 return; 82 } 83 84 // セッションID取得 85 $session_id = $this->_get_session_id(); 86 if (!$session_id) { 87 return; 88 } 89 90 // トランザクション開始 91 $this->model->begin(); 92 $query_log = $this->model->getDataSource()->getLog(); 93 $this->log('del-'.$query_log['log'][0]['query'],LOG_DEBUG); 94 95 // 対象レコードのIDを取得するためにfindする 96 $data = $this->model->find('first', array( 97 'fields' => array('id'), 98 'conditions' => array( 99 'article_id' => $article_id, 100 'session' => $session_id, 101 ), 102 )); 103 $query_log = $this->model->getDataSource()->getLog(); 104 $this->log('del-1'.$query_log['log'][0]['query'],LOG_DEBUG); 105 106 if (!$data) { 107 // ロールバック 108 $this->model->rollback(); 109 $query_log = $this->model->getDataSource()->getLog(); 110 $this->log('del-cnt(0):'.$query_log['log'][0]['query'],LOG_DEBUG); 111 $this->_error('delete target not found'); 112 return; 113 } 114 115 // レコード削除 116 $id = $data['model']['id']; 117 if($this->model->delete($id)){ 118 $query_log = $this->model->getDataSource()->getLog(); 119 $this->log('del-2'.$query_log['log'][0]['query'],LOG_DEBUG); 120 121 // コミット 122 $this->model->commit(); 123 $query_log = $this->model->getDataSource()->getLog(); 124 $this->log('del-3'.$query_log['log'][0]['query'],LOG_DEBUG); 125 } else { 126 $query_log = $this->model->getDataSource()->getLog(); 127 $this->log('del-4'.$query_log['log'][0]['query'],LOG_DEBUG); 128 129 // ロールバック 130 $this->model->rollback(); 131 $query_log = $this->model->getDataSource()->getLog(); 132 $this->log('del-5'.$query_log['log'][0]['query'],LOG_DEBUG); 133 debug('del failed'); 134 exit; 135 136 } 137 138 139 $this->set('result', true); 140 $this->set('message', 'cancel ok'); 141 142 $this->set('_serialize', array('result', 'message')); 143 144 } 145
下記のようなログの状態が正しいのですが
add-begin add-1SELECT add-2SELECT add-3commit del-bigin del-1 del-2 del-3commit
たまに下記のようなログの状態になります。
add-bigin del-bigin del-1 add-1 add-cnt(1):rollback del-2 del-3commit
回答4件
あなたの回答
tips
プレビュー