首页 > 解决方案 > 从 PHP 端处理 MySQL 事务:策略和最佳实践

问题描述

假设我有以下虚拟代码,实际上将公司(客户)信息与所有相关对象复制粘贴:

class Company extends BaseModel{
    public function companyCopyPaste($existingCompanyId)
    {

        $this->db->transaction->start();

        try{
            $newCompanyId = $this->createNewCompany($existingCompanyId);
            $this->copyPasteClientObjects($companyId, $newCompanyId)
            $this->db->transaction->commit();
        } catch(Exception $e){
            this->db->transaction->rollback();
        }

    }
    ...
}

方法copyPasteClientObjects内部包含很多逻辑,比如选择/更新现有数据、聚合和保存。此外,整个过程可能需要长达 10 秒才能完成(由于要处理大量信息) 最简单的方法是在方法的请求中启动事务并在完成后提交。但我想这不是正确的方法,但我仍然想保持一切完整,同时也避免死锁。因此,如果其中一个步骤失败,我希望回滚之前的步骤。

有什么好的建议如何正确处理这种情况?

标签: phpmysql

解决方案


这不是一个答案,而是一些意见。

如果我猜对了,您想实现从现有类型创建新的操作。

当您创建新记录时,还没有发生真正危险的事情。

我建议您以这种方式转换代码:

     try{
        $newCompanyId = $this->createNewCompany($existingCompanyId);
        $this->copyPasteClientObjects($companyId, $newCompanyId)
    } catch(Exception $e){
        this->deleteNewCompany($newCompanyId);
    }

这样您就不需要任何交易,但您deleteNewCompany应该恢复已完成但未完成的所有事情。是的,创建该功能需要做更多的工作,但对我来说,阻塞 DB 10 秒更有意义。

而且} catch(Exception $e){恕我直言不是最佳实践,您需要定义一些自定义案例特定Exception类型。喜欢CopyPasteException什么的。


推荐阅读