我试图将依赖注入模式应用于我一直致力于的中等规模项目。我的大多数类在某种程度上与数据库交互,而不是在每个类中实例化一个pdo对象,我在控制器级实例化一个pdo对象,并将此对象注入需要数据库连接的类。这样,所有类都使用相同的连接,整个过程使单元测试变得非常简单。
但是,当我尝试使用这些类的事务时,事情变得有点复杂。我们的数据库严重去标准化,每个操作都需要来自不同类的多个插入/更新。举一个基本的例子,我们假设我们有以下课程:
class student{
public function addCourse($pdo,$course){
//$pdo->execute();
}
}
class course{
public function incrementStudentCount($pdo){
//$pdo->execute();
}
}
如您所见,addCourse和incrementStudentCount方法都必须在单个事务模式下工作。但是,学生和课程类不知道$ pdo对象中是否启动了事务。他们不知道在出现问题时是否需要回滚。
我想过创建一个PDO包装类并使用这个类进行数据库交互。这样,我可以将事务状态保留在此类中。基本上,它看起来像这样:
class PDOWrapper {
private $transactionStarted=false;
private $pdo;
public function __construct($pdo){
$this->pdo=$pdo;
}
public function startTransaction(){
$this->transactionStarted=true;
$this->pdo->beginTransaction()
}
public function query($query){
try{
//$this->db->execute($query);
}
catch(PDOException e){
if($this->transactionStarted){
$this->db->rollBack();
}
}
}
}
嗯,我不确定这种方法是否可行。所以,你会建议什么?
答案 0 :(得分:1)
你说得对,你的课程不应该知道其他课程/数据库中发生了什么。这些都不重要,所有student
和user
类都在插入数据库。
无论是否存在交易都无关紧要:无论是否插入行,他们仍应该做他们正在做的完全相同的事情。我建议你有一个控制器来处理这两个任务,如下所示:
$pdo->startTransaction();
//However you instantiate the course object, do it here
$course = new Course;
//Same with student
$student = new Student;
$student->addCourse($pdo, $course);
$course->incrementStudentCount($pdo);
$pdo->commit();
当您提交数据库时,您的所有查询都将通过。如果出现错误,您可以回滚:
try
{
$pdo->startTransaction();
//Code
}
catch(PDOException $e)
{
$pdo->rollback();
}