I'm building integration tests in Lumen 5.1.3. Most of my tests roll back their transactions just fine. Here is a summary of what a successful rollback may look like (I'm simplifying the code - really the transaction management is done via a trait I've attached to PHPUnit's @before annotation):
DB::beginTransaction();
DB::table('user')->insert(
[
'guid' => $guid,
'username' => $username,
'email' => $email,
'status' => USER_STATUS_ACTIVE,
'type' => USER_TYPE_REGULAR,
'created_on' => $currentDateTime
]
);
DB::rollBack();
All is good. The user table is empty after this test.
Now - here is where I get confused. If I add an SP to the mix, things don't get rolled back:
DB::beginTransaction();
DB::table('user')->insert(
[
'guid' => $guid,
'username' => $username,
'email' => $email,
'status' => USER_STATUS_ACTIVE,
'type' => USER_TYPE_REGULAR,
'created_on' => $currentDateTime
]
);
DB::statement('CALL s_generate_leaderboards(?)', [$oneWeekAgo]);
DB::rollBack();
The new User record is indeed committed now. DB::rollBack();
has no effect once I've executed a stored proc.
There are no errors - everything succeeds. I have even made sure that the DB::rollBack();
command is being reached.
So - why is my transaction being committed if and only if I call an SP? So frustrating.. :(
EDIT 1:
Your suspicion was bang on. Here is the SP (it's large so I've collapsed 90% of it):
CREATE PROCEDURE s_generate_leaderboards (IN week_ago_date DATETIME)
BEGIN
-- Empty and regenerate the all-time leaderboard:
TRUNCATE TABLE all_time_leaderboard;
INSERT INTO all_time_leaderboard (...)
...;
-- Empty and regenerate last week's leaderboard:
TRUNCATE TABLE last_week_leaderboard;
INSERT INTO last_week_leaderboard (...)
...;
END
So maybe it's not the SP itself that is committing, but only the TRUNCATE
statements within the SP?
TRUNCATE
is being used because there is a position
column in the leaderboard tables that auto-increments, and needs to be reset. DELETE FROM table
does not reset auto-increments..