Zend_Db_Adapter :: beginTransaction() 스택이 있습니까?
다음을 고려하십시오./** (Cas_Template_Tree::DeleteNode)
* Deletes the given node from the tree, and all of it's children.
*
* @static
* @throws Exception
* @param Cas_Template_Node $node
* @return void
*/
public static function DeleteNode(Cas_Template_Node $node)
{
$table = new Cas_Table_Templates();
$adapter = $table->getAdapter();
$leftStr = $adapter->quoteIdentifier('Left');
$rightStr = $adapter->quoteIdentifier('Right');
try
{
$adapter->beginTransaction();
$row = $table->find($node->GetId())->current();
$dependantRowSelector = array(
"$leftStr >= ?" => $row->Left,
"$rightStr <= ?" => $row->Right
);
//Get the rows removed so that we can nuke the ACLs later.
$rowsToDelete = $table->fetchAll($dependantRowSelector)->toArray();
//Delete the rows.
$table->delete($dependantRowSelector);
//Delete access control lists on those rows.
foreach ($rowsToDelete as $rowToDelete)
{
Cas_Acl::CreateExisting($rowToDelete['Acl'])->Delete();
}
$left = (int)$row->Left;
$right = (int)$row->Right;
$difference = $right - $left + 1;
$table->update(array('Left' => new Zend_Db_Expr("$leftStr - $difference")),
array("$leftStr > ?" => $right));
$table->update(array('Right' => new Zend_Db_Expr("$rightStr - $difference")),
array("$rightStr > ?" => $right));
$adapter->commit();
}
catch (Exception $ex)
{
$adapter->rollBack();
throw $ex;
}
}
/** (Cas_Acl::Delete)
* Removes this ACL (and all of its dependent access control entries) from the database.
* @return void
*/
public function Delete()
{
$aclTable = new Cas_Table_AccessControlLists();
$aceTable = new Cas_Table_AccessControlEntries();
$adapter = Zend_Db_Table_Abstract::getDefaultAdapter();
$identifierName = $adapter->quoteIdentifier('Identifier');
$aclName = $adapter->quoteIdentifier('Acl');
try
{
$adapter->beginTransaction();
$aceTable->delete(array("$aclName = ?" => $this->GetId()));
$aclTable->delete(array("$identifierName = ?" => $this->GetId()));
}
catch (Exception $ex)
{
$adapter->rollBack();
throw $ex;
}
}
그렇지 않으면 조작이 어둡지 않을 수 있기 때.에 둘 다 트랜잭션 작동이 필요합니다. 원래 DeleteNode 메소드는 Cas_Acl::Delete()
를 호출합니다. Cas_Acl::Delete()
역시 트랜잭션 블록 내부에서 자체 실행을 시도합니다. 이상적으로, Zend_Db는이 경우를 인식 할만큼 똑똑 할 것이며,이 특정 호출에 대해 Cas_Acl::Delete
내부에서 begin transaction 및 commit/rollback 호출을 무시하십시오.
위의 코드가 안전할까요? 어떤 방식 으로든 크게 개선 될 수 있습니까?
'Delete()'를 직접 호출하는 경우가 있습니까? 또는'DeleteNode()'내에서만 호출 되는가? – singles
@singles : Yes - ACL을 삭제해야 할 때마다'Cas_Acl :: Delete'가 호출됩니다. 그리고이 앱이 관리하는 대부분의 모든 객체에 ACL이 첨부되어 있습니다. 이러한 객체 중 일부는 트랜잭션을 사용하지만 다른 객체는 필요하지 않습니다. –
당신의 코드가 tintin http://omg.wthax.org/haddock.jpg의 시트 위 또는 아래에있는 haddock의 수염처럼 "$ adapter-> beginTransaction();"이라고 생각합니다. – regilero