无法完成交易;超过锁定等待超时;尝试重启事务
Posted
技术标签:
【中文标题】无法完成交易;超过锁定等待超时;尝试重启事务【英文标题】:Unable to complete transaction; Lock wait timeout exceeded; try restarting transaction 【发布时间】:2013-08-10 22:55:22 【问题描述】:当我尝试运行以下代码时:
$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 [UPDATE
invoice_testSET
IDTEST=:p1 WHERE invoice_test.IDCL=:p2 ] [wrapped: SQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded; try restarting transaction]
超过锁定等待超时;尝试重启事务
我得到的错误是针对具有较少数据且仅处理一个表的表/数据库。
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.
【问题讨论】:
更新语句是什么样的? 类似这样的东西 - UPDATE invoice_test SET invoice_test.IDTEST=21 WHERE invoice_test.IDCL=2invoice_test
有多大? IDCL 上有索引吗?
很小,只有一行数据。是的,IDCL 上有一个索引。
物有所值***.com/questions/6000336/…
【参考方案1】:
似乎错误背后的原因是 idtest 的外键约束。
这里$idtest
是bud_ex表中新保存的行的primary_key;这是从 last_insert_id 中检索到的,这与尝试在 incoice_test 表中使用的 id 相同。这里的问题是,我试图使用 $idtest,但是连接/事务没有提交,因此当尝试使用这个 id 时,它抛出了一个 fk 约束错误,这反过来又超过了锁定超时。
为了让它工作,我必须运行一个查询来将发票数据库的外键检查设置为 false。
set foreign_key_checks = 0;
除此之外,我还对 php 代码进行了一些更改,以使 try catch 块更加具体。
$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;
【讨论】:
好主意...+1以上是关于无法完成交易;超过锁定等待超时;尝试重启事务的主要内容,如果未能解决你的问题,请参考以下文章
保存/更新模型时,Django“超过锁定等待超时;尝试重新启动事务”