Skip to content

Commit

Permalink
MDL-20625 new delegated transaction support in DML
Browse files Browse the repository at this point in the history
  • Loading branch information
skodak committed Nov 7, 2009
1 parent 88d39d6 commit d5a8d9a
Show file tree
Hide file tree
Showing 25 changed files with 772 additions and 424 deletions.
14 changes: 4 additions & 10 deletions auth/cas/auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -796,7 +796,7 @@ function sync_users ($do_updates = true) {
$creatorrole = false;
}

$DB->begin_sql();
$transaction = $DB->start_delegated_transaction();
$xcount = 0;
$maxxcount = 100;

Expand All @@ -816,14 +816,8 @@ function sync_users ($do_updates = true) {
role_unassign($creatorrole->id, $user->id, 0, $sitecontext->id, 'cas');
}
}

if ($xcount++ > $maxxcount) {
$DB->commit_sql();
$DB->begin_sql();
$xcount = 0;
}
}
$DB->commit_sql();
$transaction->allow_commit();
unset($users); // free mem
}
} else { // end do updates
Expand Down Expand Up @@ -851,7 +845,7 @@ function sync_users ($do_updates = true) {
$creatorrole = false;
}

$DB->begin_sql();
$transaction = $DB->start_delegated_transaction();
foreach ($add_users as $user) {
$user = $this->get_userinfo_asobj($user->username);

Expand Down Expand Up @@ -879,7 +873,7 @@ function sync_users ($do_updates = true) {
role_assign($creatorrole->id, $user->id, 0, $sitecontext->id, 0, 0, 0, 'cas');
}
}
$DB->commit_sql();
$transaction->allow_commit();
unset($add_users); // free mem
} else {
print "No users to be added\n";
Expand Down
4 changes: 2 additions & 2 deletions auth/db/auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ function sync_users($do_updates=false) {

if (!empty($add_users)) {
print_string('auth_dbuserstoadd','auth_db',count($add_users)); echo "\n";
$DB->begin_sql();
$transaction = $DB->start_delegated_transaction();
foreach($add_users as $user) {
$username = $user;
$user = $this->get_userinfo_asobj($user);
Expand Down Expand Up @@ -375,7 +375,7 @@ function sync_users($do_updates=false) {
echo "\t"; print_string('auth_dbinsertusererror', 'auth_db', $user->username); echo "\n";
}
}
$DB->commit_sql();
$transaction->allow_commit();
unset($add_users); // free mem
}
return true;
Expand Down
14 changes: 4 additions & 10 deletions auth/ldap/auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -729,7 +729,7 @@ function sync_users($do_updates=true) {
$creatorrole = false;
}

$DB->begin_sql();
$transaction = $DB->start_delegated_transaction();
$xcount = 0;
$maxxcount = 100;

Expand All @@ -749,14 +749,8 @@ function sync_users($do_updates=true) {
role_unassign($creatorrole->id, $user->id, 0, $sitecontext->id, 'ldap');
}
}

if ($xcount++ > $maxxcount) {
$DB->commit_sql();
$DB->begin_sql();
$xcount = 0;
}
}
$DB->commit_sql();
$transaction->allow_commit();
unset($users); // free mem
}
} else { // end do updates
Expand Down Expand Up @@ -785,7 +779,7 @@ function sync_users($do_updates=true) {
$creatorrole = false;
}

$DB->begin_sql();
$transaction = $DB->start_delegated_transaction();
foreach ($add_users as $user) {
$user = $this->get_userinfo_asobj($user->username);

Expand Down Expand Up @@ -816,7 +810,7 @@ function sync_users($do_updates=true) {
role_assign($creatorrole->id, $user->id, 0, $sitecontext->id, 0, 0, 0, 'ldap');
}
}
$DB->commit_sql();
$transaction->allow_commit();
unset($add_users); // free mem
} else {
print "No users to be added\n";
Expand Down
4 changes: 2 additions & 2 deletions auth/mnet/auth.php
Original file line number Diff line number Diff line change
Expand Up @@ -854,7 +854,7 @@ function refresh_log($array) {
$start = ob_start();

$returnString = '';
$DB->begin_sql();
$transaction = $DB->start_delegated_transaction();
$useridarray = array();

foreach($array as $logEntry) {
Expand Down Expand Up @@ -883,7 +883,7 @@ function refresh_log($array) {
}
}
$MNET_REMOTE_CLIENT->commit();
$DB->commit_sql();
$transaction->allow_commit();

$end = ob_end_clean();

Expand Down
5 changes: 3 additions & 2 deletions enrol/database/enrol.php
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,8 @@ function sync_enrolments($role = null) {
return true;
}

$DB->begin_sql();
$transaction = $DB->start_delegated_transaction();

$extcourses = array();
while ($extcourse_obj = (object)$rs->FetchRow()) { // there are more course records
$extcourse_obj = (object)array_change_key_case((array)$extcourse_obj , CASE_LOWER);
Expand Down Expand Up @@ -416,7 +417,7 @@ function sync_enrolments($role = null) {
$ers->close(); // release the handle
}

$DB->commit_sql();
$transaction->allow_commit();

// we are done now, a bit of housekeeping
fix_course_sortorder();
Expand Down
4 changes: 2 additions & 2 deletions group/delete.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,11 @@
if (!confirm_sesskey() ) {
print_error('confirmsesskeybad','error',$returnurl);
}
$DB->begin_sql();

foreach($groupidarray as $groupid) {
groups_delete_group($groupid);
}
$DB->commit_sql();

redirect($returnurl);
} else {
$PAGE->set_title(get_string('deleteselectedgroup', 'group'));
Expand Down
159 changes: 72 additions & 87 deletions group/externallib.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,36 +60,31 @@ public static function create_groups($groups) {

$params = self::validate_parameters(self::create_groups_parameters(), array('groups'=>$groups));

// ideally create all groups or none at all, unfortunately myisam engine does not support transactions :-(
$DB->begin_sql();
try {
//TODO: there is a potential problem with events propagating actions to external systems :-(
$groups = array();

foreach ($params['groups'] as $group) {
$group = (object)$group;

if (trim($group->name) == '') {
throw new invalid_parameter_exception('Invalid group name');
}
if ($DB->get_record('groups', array('courseid'=>$group->courseid, 'name'=>$group->name))) {
throw new invalid_parameter_exception('Group with the same name already exists in the course');
}

// now security checks
$context = get_context_instance(CONTEXT_COURSE, $group->courseid);
self::validate_context($context);
require_capability('moodle/course:managegroups', $context);

// finally create the group
$group->id = groups_create_group($group, false);
$groups[] = (array)$group;
$transaction = $DB->start_delegated_transaction();

$groups = array();

foreach ($params['groups'] as $group) {
$group = (object)$group;

if (trim($group->name) == '') {
throw new invalid_parameter_exception('Invalid group name');
}
if ($DB->get_record('groups', array('courseid'=>$group->courseid, 'name'=>$group->name))) {
throw new invalid_parameter_exception('Group with the same name already exists in the course');
}
} catch (Exception $ex) {
$DB->rollback_sql();
throw $ex;

// now security checks
$context = get_context_instance(CONTEXT_COURSE, $group->courseid);
self::validate_context($context);
require_capability('moodle/course:managegroups', $context);

// finally create the group
$group->id = groups_create_group($group, false);
$groups[] = (array)$group;
}
$DB->commit_sql();

$transaction->allow_commit();

return $groups;
}
Expand Down Expand Up @@ -242,30 +237,27 @@ public static function delete_groups($groupids) {

$params = self::validate_parameters(self::delete_groups_parameters(), array('groupids'=>$groupids));

$DB->begin_sql();
try {
$transaction = $DB->start_delegated_transaction();

// TODO: this is problematic because the DB rollback does not handle deleting of images!!
// there is also potential problem with events propagating action to external systems :-(
foreach ($params['groupids'] as $groupid) {
// validate params
$groupid = validate_param($groupid, PARAM_INTEGER);
if (!$group = groups_get_group($groupid, 'id, courseid', IGNORE_MISSING)) {
// silently ignore attempts to delete nonexisting groups
continue;
}

// now security checks
$context = get_context_instance(CONTEXT_COURSE, $group->courseid);
self::validate_context($context);
require_capability('moodle/course:managegroups', $context);

groups_delete_group($group);
foreach ($params['groupids'] as $groupid) {
// validate params
$groupid = validate_param($groupid, PARAM_INTEGER);
if (!$group = groups_get_group($groupid, 'id, courseid', IGNORE_MISSING)) {
// silently ignore attempts to delete nonexisting groups
continue;
}
} catch (Exception $ex) {
$DB->rollback_sql();
throw $ex;

// now security checks
$context = get_context_instance(CONTEXT_COURSE, $group->courseid);
self::validate_context($context);
require_capability('moodle/course:managegroups', $context);

groups_delete_group($group);
}
$DB->commit_sql();

$transaction->allow_commit();
}

/**
Expand Down Expand Up @@ -361,33 +353,29 @@ public static function add_groupmembers($members) {

$params = self::validate_parameters(self::add_groupmembers_parameters(), array('members'=>$members));

$DB->begin_sql();
try {
// TODO: there is a potential problem with events propagating action to external systems :-(
foreach ($params['members'] as $member) {
// validate params
$groupid = $member['groupid'];
$userid = $member['userid'];
$transaction = $DB->start_delegated_transaction();
// TODO: there is a potential problem with events propagating action to external systems :-(
foreach ($params['members'] as $member) {
// validate params
$groupid = $member['groupid'];
$userid = $member['userid'];

$group = groups_get_group($groupid, 'id, courseid', MUST_EXIST);
$user = $DB->get_record('user', array('id'=>$userid, 'deleted'=>0, 'mnethostid'=>$CFG->mnet_localhost_id), '*', MUST_EXIST);
$group = groups_get_group($groupid, 'id, courseid', MUST_EXIST);
$user = $DB->get_record('user', array('id'=>$userid, 'deleted'=>0, 'mnethostid'=>$CFG->mnet_localhost_id), '*', MUST_EXIST);

// now security checks
$context = get_context_instance(CONTEXT_COURSE, $group->courseid);
self::validate_context($context);
require_capability('moodle/course:managegroups', $context);
// now security checks
$context = get_context_instance(CONTEXT_COURSE, $group->courseid);
self::validate_context($context);
require_capability('moodle/course:managegroups', $context);

// now make sure user is enrolled in course - this is mandatory requirement,
// unfortunately this is extermely slow
require_capability('moodle/course:view', $context, $userid, false);
// now make sure user is enrolled in course - this is mandatory requirement,
// unfortunately this is extermely slow
require_capability('moodle/course:view', $context, $userid, false);

groups_add_member($group, $user);
}
} catch (Exception $ex) {
$DB->rollback_sql();
throw $ex;
groups_add_member($group, $user);
}
$DB->commit_sql();

$transaction->allow_commit();
}

/**
Expand Down Expand Up @@ -429,29 +417,26 @@ public static function delete_groupmembers($members) {

$params = self::validate_parameters(self::delete_groupmembers_parameters(), array('members'=>$members));

$DB->begin_sql();
try {
$transaction = $DB->start_delegated_transaction();

// TODO: there is a potential problem with events propagating action to external systems :-(
foreach ($params['members'] as $member) {
// validate params
$groupid = $member['groupid'];
$userid = $member['userid'];
// validate params
$groupid = $member['groupid'];
$userid = $member['userid'];

$group = groups_get_group($groupid, 'id, courseid', MUST_EXIST);
$user = $DB->get_record('user', array('id'=>$userid, 'deleted'=>0, 'mnethostid'=>$CFG->mnet_localhost_id), '*', MUST_EXIST);
$group = groups_get_group($groupid, 'id, courseid', MUST_EXIST);
$user = $DB->get_record('user', array('id'=>$userid, 'deleted'=>0, 'mnethostid'=>$CFG->mnet_localhost_id), '*', MUST_EXIST);

// now security checks
$context = get_context_instance(CONTEXT_COURSE, $group->courseid);
self::validate_context($context);
require_capability('moodle/course:managegroups', $context);
// now security checks
$context = get_context_instance(CONTEXT_COURSE, $group->courseid);
self::validate_context($context);
require_capability('moodle/course:managegroups', $context);

groups_remove_member($group, $user);
}
} catch (Exception $ex) {
$DB->rollback_sql();
throw $ex;
groups_remove_member($group, $user);
}
$DB->commit_sql();

$transaction->allow_commit();
}

/**
Expand Down
1 change: 1 addition & 0 deletions lang/en_utf8/error.php
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@
$string['ddlunknownerror'] = 'Unknown DDL library error';
$string['ddlxmlfileerror'] = 'XML database file errors found';
$string['dmlreadexception'] = 'Error reading from database';
$string['dmltransactionexception'] = 'Database transaction error';
$string['dmlwriteexception'] = 'Error writing to database';
$string['destinationcmnotexit'] = 'The destination course module does not exist';
$string['detectedbrokenplugin'] = 'Plugin \"$a\" is defective, can not continue, sorry.';
Expand Down
20 changes: 7 additions & 13 deletions lib/accesslib.php
Original file line number Diff line number Diff line change
Expand Up @@ -2455,24 +2455,18 @@ function cleanup_contexts() {
ON c.instanceid = t.id
WHERE t.id IS NULL AND c.contextlevel = ".CONTEXT_BLOCK."
";

// transactions used only for performance reasons here
$transaction = $DB->start_delegated_transaction();

if ($rs = $DB->get_recordset_sql($sql)) {
$DB->begin_sql();
$ok = true;
foreach ($rs as $ctx) {
if (!delete_context($ctx->contextlevel, $ctx->instanceid)) {
$ok = false;
break;
}
delete_context($ctx->contextlevel, $ctx->instanceid);
}
$rs->close();
if ($ok) {
$DB->commit_sql();
return true;
} else {
$DB->rollback_sql();
return false;
}
}

$transaction->allow_commit();
return true;
}

Expand Down
Loading

0 comments on commit d5a8d9a

Please sign in to comment.