Forum OpenACS Development: Transactions and recurssion

Collapse
Posted by Caroline Meeks on
I just modified dotlrn_community::archive so that it will archive subcommunities. I modeled the code after dotlrn_community::remove_user which also does recurssion inside a transaction and it works fine on dev but I'm still nervous that I could end up with too many transactions inside transactions and have deadlock problems.

Note that dotLRN can have arbitrary levels of subcommunities of subcommunities. I think 4 levels is the most currently used on SloanSpace.

Here is the code.

  ad_proc -public archive {
        {-community_id:required}
    } {
        Archives a community. This means that:
        1. the community is marked as archived
        2. the RemovePortlet callback is called for all users of the
        community (both members and GAs) and all the applets.
        3. Do this recursively for all subcommunities.
    } {
        db_transaction {
            foreach subcomm_id [get_subcomm_list -community_id $community_id] {
                archive -community_id $subcomm_id
            }
            # do RemoveUserFromCommunity callback, which
            # calls the RemovePortlet proc with the right params


            foreach user [list_users $community_id] {
                set user_id [ns_set get $user user_id]
                applets_dispatch \
                        -community_id $community_id \
                        -op RemoveUserFromCommunity \
                        -list_args [list $community_id $user_id]
            }

            # mark the community as archived
            db_dml update_archive_p {}
        }
    }

Should I take the subcommunity code out of the transaction. In this situation as long as each subcommunity is fully archived it wouldn't be that horrible if the proc failed with only some of the subcommunities archived.

Collapse
Posted by Andrew Piskorski on
Interesting question. The latest code for db_transaction says:
Multiple db_transactions may be nested (end transaction is transparently ns_db dml'ed when the outermost transaction completes).

So, I believe that means that any nested db_transactions are effectively converted into one big flat transaction.

Has anyone thought about making nested db_transactions instead set savepoints, so that if an inner transaction aborts it rolls back to the savepoint, rather than aborting all the outer db_transactions as well? I know that should be possible in Oracle (whether it's a good idea or not is another question), but does Postgres have savepoints?

Collapse
Posted by Ben Adida on
Might be a good idea, although it's tough to figure out what you would do if you failed on the inner transaction: would you really keep going with the outer one in a web environment?

Either way, PG does not currently have save points. Burce Momjan is working on them for 7.4 or 7.5.