0

I'm trying to adopt dependency injection pattern to a mid-scale project that I have been working on. Most of my classes interact with database on some level and instead of instantiating a pdo object inside each class, I instantiate a single pdo object on controller level and inject this object to classes that require a database connection. This way, all classes are using the same connection and the whole process is making the unit testing pretty easy.

However, things get a little bit complex when I try to use transaction with these classes. Our database is heavily de-normalized and each action requires multiple inserts/updates from different classes. To give a basic example, let's say we have the classes below:

    class student{
        public function addCourse($pdo,$course){
            //$pdo->execute();
        }
    }

    class course{
        public function incrementStudentCount($pdo){
            //$pdo->execute();
        }
    }

As you see, both addCourse and incrementStudentCount methods must work in a single transaction mode.However,student and course classes are not aware of whether a transaction started or not in $pdo object. They don't know if a rollback is required in case a problem occurs.

I thought of creating a PDO wrapper class and using this class for database interactions. This way, I can keep the transaction state inside this class. Basically, it looks something like this:

    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();
                }
            }
        }
    }

Well, I'm not sure this approach is the way to go. So, what would you suggest?

1
  • So whats the issue you have or are trying to overcome with the code you came up with? Commented Apr 9, 2015 at 19:28

1 Answer 1

1

You're right in that your classes should not know what is going on in the other class / DB. None of that matters, all the student and user classes are concerned with are inserting to the database.

It shouldn't matter if there's a transaction or not: they should still be doing the exact same thing they'd be doing regardless, which is inserting rows. I'd recommend you have a controller that takes care of both tasks, like so:

$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();

When you commit to the database, all your queries will go through. You can rollback in case of an error like so:

try
{
    $pdo->startTransaction();
    //Code
}
catch(PDOException $e)
{
    $pdo->rollback();
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.