Index: openacs-4/packages/acs-tcl/tcl/security-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-tcl/tcl/security-procs.tcl,v diff -u -r1.5 -r1.6 --- openacs-4/packages/acs-tcl/tcl/security-procs.tcl 9 Feb 2002 02:33:35 -0000 1.5 +++ openacs-4/packages/acs-tcl/tcl/security-procs.tcl 28 Feb 2002 01:10:08 -0000 1.6 @@ -386,19 +386,28 @@ set last_hit [ns_time] db_transaction { - db_dml prop_delete_dml { - delete from sec_session_properties - where session_id = :session_id - and module = :module - and property_name = :name - } - set clob_dml [db_map prop_insert_dml_clob] + # DRB: Older versions of this code did a delete/insert pair in an attempt + # to guard against duplicate insertions. This didn't work if there were + # no value for this property in the table and two transactions ran in + # parallel. The problem is that without an existing row the delete had + # nothing to lock on, thus allowing the two inserts to conflict. This + # was discovered on a page built of frames, where the two requests from + # the browser spawned two AOLserver threads to service them. + # This code's a bit crude in that we assume the only error we get will + # be due to a unique violation, so be careful if you edit the queries! + + set clob_insert_dml [db_map prop_insert_dml_clob] + if { $clob == "t" && ![empty_string_p $clob_dml] } { - db_dml dummy $clob_dml -clobs [list $value] + if { [catch {db_dml dummy $clob_dml -clobs [list $value]} errmsg] } { + db_dml prop_update_dml_clob "" -clobs [list $value] + } } else { - db_dml prop_insert_dml "" + if { [catch {db_dml prop_insert_dml ""} ] } { + db_dml prop_update_dml "" + } } } }