0

以下のコードを実行しようとすると:

    $conBud = Propel::getConnection(MyTestBudgetPeer::DATABASE_NAME); // DATABASE_NAME = 'Budget'
    $conBud->beginTransaction();        
    $conIn = Propel::getConnection(MyTestInvoicePeer::DATABASE_NAME);  // DATABASE_NAME = 'Invoice'
    $conIn->beginTransaction();
    $idcl = '1235';
    try
    {
      // Do db udpates related to database Budget (here around 15 tables and 500 data rows are update)
       // budExModel is a table, primary id from this table is used to update InvoiceTest Table below
       $idtest = $budExModel->save($conBud);
       ...
      // Code to Update one table for database Invoice (only one table)
      // Create a Criteria object that will select the correct rows from the database
        $selectCriteria = new Criteria();
        $selectCriteria->add(InvoiceTestPeer::IDCL, $idcl, Criteria::EQUAL);            
        $selectCriteria->setDbName(InvoiceTestPeer::DATABASE_NAME);
        // Create a Criteria object includes the value you want to set
        $updateCriteria = new Criteria();
        $updateCriteria->add(InvoiceTestPeer::IDTEST, $idtest);
        // Execute the query
        BasePeer::doUpdate($selectCriteria, $updateCriteria, $conIn);

        $conBud->commit();
        $conIn->commit();           
    } catch (Exception $e)
    {
        $conBud->rollBack();
        $conIn->rollBack(); 
    }

次のエラーが表示されます: ["Unable to execute UPDATE statement [UPDATEinvoice_test SETIDTEST=:p1 WHERE invoice_test.IDCL=:p2 ] [wrapped: SQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded; try restarting transaction]

ロック待機タイムアウトを超えました。トランザクションを再開してみてください

私が得ているエラーは、データが少なく、1 つのテーブルのみを処理する table/db に対するものです。

これはmysqlでは許可されていませんか?

すでに innodb_lock_wait_timeout を変更し、mysql を再起動しようとしたため、オプションではありません。

Edit: Here IDTEST I am trying to udpate for table invoice_test is an fk from Table Budget_test from database Budget.
4

1 に答える 1

2

エラーの背後にある理由は、idtest の外部キー制約だったようです。

これは、テーブルbud_ex$idtestから新しく保存された行の primary_key です。これは last_insert_id から取得されたもので、incoice_test テーブルで使用しようとしていたのと同じ ID でした。ここでの問題は、$idtest を使用しようとしていたのですが、接続/トランザクションがコミットされなかったため、この ID を使用しようとすると、fk 制約エラーがスローされ、ロック タイムアウトが超過しました。

これを機能させるには、クエリを実行して、請求書データベースの外部キー チェックを false に設定する必要がありました。

set foreign_key_checks = 0; 

これに伴い、try catch ブロックをより具体的にするために、php コードにいくつかの変更を加えました。

$con1->beginTransaction();
try
{
    // Do stuff
    $con2->beginTransaction();
    try
    {
        // Do stuff
        $con2->commitTransaction();
    }
    catch (Exception $e)
    {
        $con2->rollbackTransaction();
        throw $e;
    }
    try
    {
        $con1->commitTransaction();
    }
    catch (Exception $e)
    {
        // Oops $con2 was already committed, we need to manually revert operations done with $con2
        throw $e;
    }
}
catch (Exception $e)
{
    $con1->rollbackTransaction();
    throw $e;
}
于 2013-12-02T02:54:25.407 に答える