Merge branch 'w39_MDL-35506_m24_pgerrorrollback' of git://github.com/skodak/moodle

This commit is contained in:
Dan Poltawski 2012-09-26 17:01:39 +08:00
commit ce77b89a18
2 changed files with 63 additions and 17 deletions

View File

@ -226,15 +226,6 @@ class pgsql_native_moodle_database extends moodle_database {
* @return void
*/
protected function query_start($sql, array $params=null, $type, $extrainfo=null) {
if ($this->is_transaction_started() and $type != SQL_QUERY_AUX) {
$res = @pg_query($this->pgsql, "SAVEPOINT moodle_pg_savepoint");
if ($res) {
pg_free_result($res);
}
$this->savepointpresent = true;
} else {
$this->savepointpresent = false;
}
parent::query_start($sql, $params, $type, $extrainfo);
// pgsql driver tents to send debug to output, we do not need that ;-)
$this->last_error_reporting = error_reporting(0);
@ -250,20 +241,18 @@ class pgsql_native_moodle_database extends moodle_database {
error_reporting($this->last_error_reporting);
try {
parent::query_end($result);
if ($this->savepointpresent) {
$res = @pg_query($this->pgsql, "RELEASE SAVEPOINT moodle_pg_savepoint");
if ($this->savepointpresent and $this->last_type != SQL_QUERY_AUX and $this->last_type != SQL_QUERY_SELECT) {
$res = @pg_query($this->pgsql, "RELEASE SAVEPOINT moodle_pg_savepoint; SAVEPOINT moodle_pg_savepoint");
if ($res) {
pg_free_result($res);
}
$this->savepointpresent = false;
}
} catch (Exception $e) {
if ($this->savepointpresent) {
$res = @pg_query($this->pgsql, "ROLLBACK TO SAVEPOINT moodle_pg_savepoint");
$res = @pg_query($this->pgsql, "ROLLBACK TO SAVEPOINT moodle_pg_savepoint; SAVEPOINT moodle_pg_savepoint");
if ($res) {
pg_free_result($res);
}
$this->savepointpresent = false;
}
throw $e;
}
@ -1299,7 +1288,8 @@ class pgsql_native_moodle_database extends moodle_database {
* @return void
*/
protected function begin_transaction() {
$sql = "BEGIN ISOLATION LEVEL READ COMMITTED";
$this->savepointpresent = true;
$sql = "BEGIN ISOLATION LEVEL READ COMMITTED; SAVEPOINT moodle_pg_savepoint";
$this->query_start($sql, NULL, SQL_QUERY_AUX);
$result = pg_query($this->pgsql, $sql);
$this->query_end($result);
@ -1313,7 +1303,8 @@ class pgsql_native_moodle_database extends moodle_database {
* @return void
*/
protected function commit_transaction() {
$sql = "COMMIT";
$this->savepointpresent = false;
$sql = "RELEASE SAVEPOINT moodle_pg_savepoint; COMMIT";
$this->query_start($sql, NULL, SQL_QUERY_AUX);
$result = pg_query($this->pgsql, $sql);
$this->query_end($result);
@ -1327,7 +1318,8 @@ class pgsql_native_moodle_database extends moodle_database {
* @return void
*/
protected function rollback_transaction() {
$sql = "ROLLBACK";
$this->savepointpresent = false;
$sql = "RELEASE SAVEPOINT moodle_pg_savepoint; ROLLBACK";
$this->query_start($sql, NULL, SQL_QUERY_AUX);
$result = pg_query($this->pgsql, $sql);
$this->query_end($result);

View File

@ -4199,6 +4199,7 @@ class dml_testcase extends database_driver_testcase {
$table->add_index('course', XMLDB_INDEX_UNIQUE, array('course'));
$dbman->create_table($table);
// Test error on SQL_QUERY_INSERT.
$transaction = $DB->start_delegated_transaction();
$this->assertEquals(0, $DB->count_records($tablename));
$DB->insert_record($tablename, (object)array('course'=>1));
@ -4213,6 +4214,59 @@ class dml_testcase extends database_driver_testcase {
$transaction->allow_commit();
$this->assertEquals(2, $DB->count_records($tablename));
$this->assertFalse($DB->is_transaction_started());
// Test error on SQL_QUERY_SELECT.
$DB->delete_records($tablename);
$transaction = $DB->start_delegated_transaction();
$this->assertEquals(0, $DB->count_records($tablename));
$DB->insert_record($tablename, (object)array('course'=>1));
$this->assertEquals(1, $DB->count_records($tablename));
try {
$DB->get_records_sql('s e l e c t');
} catch (Exception $e) {
// This must be ignored and it must not roll back the whole transaction.
}
$DB->insert_record($tablename, (object)array('course'=>2));
$this->assertEquals(2, $DB->count_records($tablename));
$transaction->allow_commit();
$this->assertEquals(2, $DB->count_records($tablename));
$this->assertFalse($DB->is_transaction_started());
// Test error on structure SQL_QUERY_UPDATE.
$DB->delete_records($tablename);
$transaction = $DB->start_delegated_transaction();
$this->assertEquals(0, $DB->count_records($tablename));
$DB->insert_record($tablename, (object)array('course'=>1));
$this->assertEquals(1, $DB->count_records($tablename));
try {
$DB->execute('xxxx');
} catch (Exception $e) {
// This must be ignored and it must not roll back the whole transaction.
}
$DB->insert_record($tablename, (object)array('course'=>2));
$this->assertEquals(2, $DB->count_records($tablename));
$transaction->allow_commit();
$this->assertEquals(2, $DB->count_records($tablename));
$this->assertFalse($DB->is_transaction_started());
// Test error on structure SQL_QUERY_STRUCTURE.
$DB->delete_records($tablename);
$transaction = $DB->start_delegated_transaction();
$this->assertEquals(0, $DB->count_records($tablename));
$DB->insert_record($tablename, (object)array('course'=>1));
$this->assertEquals(1, $DB->count_records($tablename));
try {
$DB->change_database_structure('xxxx');
} catch (Exception $e) {
// This must be ignored and it must not roll back the whole transaction.
}
$DB->insert_record($tablename, (object)array('course'=>2));
$this->assertEquals(2, $DB->count_records($tablename));
$transaction->allow_commit();
$this->assertEquals(2, $DB->count_records($tablename));
$this->assertFalse($DB->is_transaction_started());
// NOTE: SQL_QUERY_STRUCTURE is intentionally not tested here because it should never fail.
}
function test_onelevel_rollback() {