2017-06-03 37 views
0

保留中のロックまたはまだ開いていないMySql DB上のトランザクションが原因で、まだクエリが実行できないPHPコードがあります。 スクリプトは毎時cronによって起動されます。問題のあるコードがこのMySqlで保留中のロックまたはトランザクションを検索

CommandHelper::log("Calling beginTransaction for item $item->id"); 
    $transaction = Yii::app()->db->beginTransaction(); 
    CommandHelper::log("Trying to get update lock for item $item->id"); 
    try { 
     // this line will lock a single row 
     $item = Item::model()->findBySql("SELECT * FROM " . $item::model()->getTableSchema()->name . " WHERE id=$item->id FOR UPDATE"); 
     if(!$item) 
      throw new Exception("Item $item->id not found in processItem"); 
     CommandHelper::log("Obtained update lock for item $item->id"); 


    $now = DateTimeHelper::getInstance()->getStringNow(); 
    // the following call executes a few queries and causes an exception 
    $this->processExpiredDeferredPayments($item,$now); 
    // we won't get here 
    CommandHelper::log("Item $item->id query confirmed units"); 
    .... 
    .... 

     $transaction->commit(); 

    } catch (Exception $e) { 
     $transaction->rollBack();    
     CommandHelper::log("Transaction error:" . $e->getMessage()); 
    } 

あるログはこれらの行ごとに時間を出力します。

... 
... 
2017-06-03 14:46:04 Item 164 start processing 
2017-06-03 14:46:04 Calling beginTransaction for item 164 
2017-06-03 14:46:04 Trying to get update lock for item 164 
2017-06-03 14:46:04 Obtained update lock for item 164 
2017-06-03 14:46:04 Transaction error:There is already an active transaction 
2017-06-03 14:46:04 Item 164 end processing 
2017-06-03 14:46:04 Item 160 start processing 
2017-06-03 14:46:04 Calling beginTransaction for item 160 
2017-06-03 14:46:04 Trying to get update lock for item 160 
2017-06-03 14:46:04 Obtained update lock for item 160 
2017-06-03 14:46:04 Transaction error:There is already an active transaction 
2017-06-03 14:46:04 Item 160 end processing 
2017-06-03 14:46:04 Item 182 start processing 
2017-06-03 14:46:04 Calling beginTransaction for item 182 
2017-06-03 14:46:04 Trying to get update lock for item 182 
2017-06-03 14:46:04 Obtained update lock for item 182 
2017-06-03 14:46:04 Transaction error:There is already an active transaction 
2017-06-03 14:46:04 Item 182 end processing 
... 
... 

これはshow engine innodb status

===================================== 
2017-06-03 15:00:16 2af55a655700 INNODB MONITOR OUTPUT 
===================================== 
Per second averages calculated from the last 10 seconds 
----------------- 
BACKGROUND THREAD 
----------------- 
srv_master_thread loops: 139314 srv_active, 0 srv_shutdown, 2478167 srv_idle 
srv_master_thread log flush and writes: 2617481 
---------- 
SEMAPHORES 
---------- 
OS WAIT ARRAY INFO: reservation count 139170 
OS WAIT ARRAY INFO: signal count 139073 
Mutex spin waits 15233, rounds 456961, OS waits 14580 
RW-shared spins 123701, rounds 3711390, OS waits 123173 
RW-excl spins 89, rounds 42528, OS waits 1410 
Spin rounds per wait: 30.00 mutex, 30.00 RW-shared, 477.84 RW-excl 
------------ 
TRANSACTIONS 
------------ 
Trx id counter 233590159 
Purge done for trx's n:o < 233589999 undo n:o < 0 state: running but idle 
History list length 2636 
LIST OF TRANSACTIONS FOR EACH SESSION: 
---TRANSACTION 225441219, not started 
MySQL thread id 271018, OS thread handle 0x2af55a655700, query id 28702104 172.31.10.242 ebroot init 
show engine innodb status 
---TRANSACTION 0, not started 
MySQL thread id 271017, OS thread handle 0x2af55bfa6700, query id 28698794 172.31.10.242 ebroot cleaning up 
---TRANSACTION 233590158, not started 
MySQL thread id 1, OS thread handle 0x2af55a550700, query id 28702102 localhost 127.0.0.1 rdsadmin cleaning up 
    -------- 
    FILE I/O 
    -------- 
    ... 
    ... 

の出力であり、これはshow full processlistの出力です:

enter image description here

ここで保留中のトランザクションまたはロックはどのようにして殺すのですか?

なぜPHPスクリプトが終了したときに自動的に閉じられなかったのですか? PHPスレッドがMySQL接続を持っていても、スレッドが終了するとMySQL接続が自動的に閉じられ、トランザクション/ロックが自動的にコミットまたはロールバックされる必要があると私は考えましたか? ありがとう

+0

のためにアップグレードする必要私は、彼らが立ち往生しているInnoDBの状況ショーで一部のトランザクション気付かない「クリーンアップを。」これはhttps://stackoverflow.com/a/44289981/20860に似ていますので、私の答えを見てください。同じバグがあなたに影響を与えている場合は、MySQLをアップグレードすると役に立ちます。 –

答えて

0

私は問題を発見しました。

processExpiredDeferredPaymentsメソッドの中で私はそこで別のトランザクションを開いていることを忘れていました。トランザクションが既に開かれていたので、Mysqlは例外を発生させました。

これはMysql 5.16と5.35の両方で動作します。今

おかげで皆

関連する問題