diff --git a/lib/dml/moodle_database.php b/lib/dml/moodle_database.php index e1d2a44576a..4b454abb89c 100644 --- a/lib/dml/moodle_database.php +++ b/lib/dml/moodle_database.php @@ -2378,6 +2378,8 @@ abstract class moodle_database { // now enable transactions again $this->transactions = array(); $this->force_rollback = false; + + \core\event\manager::database_transaction_rolledback(); } /** diff --git a/lib/tests/event_test.php b/lib/tests/event_test.php index 8f68ef032f8..aadc09783c0 100644 --- a/lib/tests/event_test.php +++ b/lib/tests/event_test.php @@ -451,6 +451,101 @@ class core_event_testcase extends advanced_testcase { \core_tests\event\unittest_observer::$info); } + public function test_rollback() { + global $DB; + + $this->resetAfterTest(); + $this->preventResetByRollback(); + + $observers = array( + array( + 'eventname' => '\core_tests\event\unittest_executed', + 'callback' => '\core_tests\event\unittest_observer::external_observer', + 'internal' => 0, + ), + ); + + \core\event\manager::phpunit_replace_observers($observers); + \core_tests\event\unittest_observer::reset(); + + $this->assertCount(0, \core_tests\event\unittest_observer::$event); + + \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>1, 'xx'=>10)))->trigger(); + $this->assertCount(1, \core_tests\event\unittest_observer::$event); + \core_tests\event\unittest_observer::reset(); + + $transaction1 = $DB->start_delegated_transaction(); + + \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>1, 'xx'=>10)))->trigger(); + $this->assertCount(0, \core_tests\event\unittest_observer::$event); + + $transaction2 = $DB->start_delegated_transaction(); + + \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>1, 'xx'=>10)))->trigger(); + $this->assertCount(0, \core_tests\event\unittest_observer::$event); + + try { + $transaction2->rollback(new Exception('x')); + $this->fail('Expecting exception'); + } catch (Exception $e) {} + $this->assertCount(0, \core_tests\event\unittest_observer::$event); + + $this->assertTrue($DB->is_transaction_started()); + + try { + $transaction1->rollback(new Exception('x')); + $this->fail('Expecting exception'); + } catch (Exception $e) {} + $this->assertCount(0, \core_tests\event\unittest_observer::$event); + + $this->assertFalse($DB->is_transaction_started()); + + \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>1, 'xx'=>10)))->trigger(); + $this->assertCount(1, \core_tests\event\unittest_observer::$event); + } + + public function test_forced_rollback() { + global $DB; + + $this->resetAfterTest(); + $this->preventResetByRollback(); + + $observers = array( + array( + 'eventname' => '\core_tests\event\unittest_executed', + 'callback' => '\core_tests\event\unittest_observer::external_observer', + 'internal' => 0, + ), + ); + + \core\event\manager::phpunit_replace_observers($observers); + \core_tests\event\unittest_observer::reset(); + + $this->assertCount(0, \core_tests\event\unittest_observer::$event); + + \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>1, 'xx'=>10)))->trigger(); + $this->assertCount(1, \core_tests\event\unittest_observer::$event); + \core_tests\event\unittest_observer::reset(); + + $transaction1 = $DB->start_delegated_transaction(); + + \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>1, 'xx'=>10)))->trigger(); + $this->assertCount(0, \core_tests\event\unittest_observer::$event); + + $transaction2 = $DB->start_delegated_transaction(); + + \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>1, 'xx'=>10)))->trigger(); + $this->assertCount(0, \core_tests\event\unittest_observer::$event); + + $DB->force_transaction_rollback(); + $this->assertCount(0, \core_tests\event\unittest_observer::$event); + + $this->assertFalse($DB->is_transaction_started()); + + \core_tests\event\unittest_executed::create(array('context'=>\context_system::instance(), 'other'=>array('sample'=>1, 'xx'=>10)))->trigger(); + $this->assertCount(1, \core_tests\event\unittest_observer::$event); + } + public function test_legacy() { global $DB;