How access xml file in a thread-safe manner, using classic asp?

M

Mats Olsson

I have an xml file, which is to be updated by an asp script (vbs) when users
are submitting forms from their browsers. Now I wonder if there is anything
that stops the following to occur:

1. User A submits form, resulting in asp script to create
MSXML2.DOMDocument.4.0, which loads the xml file and updates the in-memory
DOM tree
2. User B submits form, roughly at the same time, also resulting in asp
script to create MSXML2.DOMDocument.4.0, which loads the same xml file and
updates its own in-memory DOM tree
3. The thread handling user A saves its updated DOM tree back to disk,
replacing the original file
4. The thread handling user B saves its updated DOM tree back to disk,
replacing the file containing the updates just saved for user A

Is the above something that can happen, using IIS 5 and ASP script?

If so, would storing a FreeThreadedDOMDocument.4.0 in the Application
variable be a good way to fix this, or are there any better approaches?

Any help on this would be appreciated, since I am a little lost when it
comes to threading and asp.

Mats Olsson
 
B

Bob Barrows [MVP]

Mats said:
I have an xml file, which is to be updated by an asp script (vbs)
when users are submitting forms from their browsers. Now I wonder if
there is anything that stops the following to occur:

1. User A submits form, resulting in asp script to create
MSXML2.DOMDocument.4.0, which loads the xml file and updates the
in-memory DOM tree
2. User B submits form, roughly at the same time, also resulting in
asp script to create MSXML2.DOMDocument.4.0, which loads the same xml
file and updates its own in-memory DOM tree
3. The thread handling user A saves its updated DOM tree back to disk,
replacing the original file
4. The thread handling user B saves its updated DOM tree back to disk,
replacing the file containing the updates just saved for user A

Is the above something that can happen, using IIS 5 and ASP script?

Of course
If so, would storing a FreeThreadedDOMDocument.4.0 in the Application
variable be a good way to fix this, or are there any better
approaches?

Any help on this would be appreciated, since I am a little lost when
it comes to threading and asp.

What are you trying to prevent? Shouldn't both users be allowed to save
their changes? Isn't user B allowed to overwrite changes made by user A?

It sounds like you need to use a database rather than XML or a file.
 
M

Mats Olsson

Bob,

thanks for your reply. What I am trying to prevent is user B effectively
clearing any additions/removals made by user A. In my scenario they both
start off with identical DOM trees (in different threads), due to the fact
that they happened to submit their forms at the same time. Now, suppose user
A added elements to the DOM tree before it was saved, then those elements
would get lost when the DOM tree from user B was saved to disk, since those
elements were not part of the user B's original DOM.

I could use a database, but I would prefer to be able to use the tree
structure of a DOM. That is why I thought that a shared in-memory DOM tree
(FreeThreaded), stored in the Application variable, would fix the problem
described above and below. Is there any reason why this approach would not
work?

Mats Olsson
 
B

Bob Barrows [MVP]

Mats said:
Bob,

thanks for your reply. What I am trying to prevent is user B
effectively clearing any additions/removals made by user A. In my
scenario they both start off with identical DOM trees (in different
threads), due to the fact that they happened to submit their forms at
the same time. Now, suppose user A added elements to the DOM tree
before it was saved, then those elements would get lost when the DOM
tree from user B was saved to disk, since those elements were not
part of the user B's original DOM.

I could use a database, but I would prefer to be able to use the tree
structure of a DOM. That is why I thought that a shared in-memory DOM
tree (FreeThreaded), stored in the Application variable, would fix
the problem described above and below. Is there any reason why this
approach would not work?

Yes. You could lock the application object while user A updated the DOM, but
when user B performs his updates, his DOM document will still contain the
pre-userA-update data and will overwrite the changes made by user A, given
that you are talking about replacing the entire application dom document
with the user's dom document.

You could add attributes to the dom document nodes to indicate which nodes
were changed and only update the relevant nodes in the application document,
but even this approach would not be perfect. However, it would be better
than simply overwriting the entire application dom document. The only
perfect approach would be to have a separate dom document for each user, but
this is apt to take up a significant amount of server memory.

Bob Barrows
 
M

Mats Olsson

Bob,

thanks again, but my idea was to have one DOM only, i.e. the FreeThreaded
one stored in the Application object. The asp script handling submitted
forms would then add elements to this DOM, as well as look up existing ones
in order to update them or remove them. The "worst" thing that could happen
(unless I have missed something) is that the thread handling user A just
removed an element which was the update "target" for user B. But that's ok.
And, of course, each asp script round would end with the DOM being saved to
disk.

Do you still feel that this would not work?

Mats Olsson
 
M

Mats Olsson

Oops, I actually meant the Application variable, not the Application object.
Mats
 
B

Bob Barrows [MVP]

The "Save to disk" part is where you will run into problems if I understand
what you mean by "each asp script round". When the DOM in Application is
saved to disk, it will completely overwrite the disk version.

You're really better off using a database when concurrency is an issue. I
can't stress that enough.
 
J

Just1Coder

I have the following function that is to import HTML data from a URL to
a MS-SQL table:

function gethtml(str)
'on error resume next
dim xmlhttp
set xmlhttp = Server.CreateObject("MSXML2.ServerXMLHTTP")
xmlhttp.open "GET", str, false
xmlhttp.send
newcontent = trim(xmlhttp.responseText)
if err.number <> 0 then
newcontent = "Error Retrieving URL, Please try again."
end if
set xmlhttp = nothing
' response.write ("<xmp>")
response.write (newcontent)
' response.write ("</xmp>")
end function

Works almost perfectly ... the URL's HTML is sucked in but the
whitespace is converted to ?'s.
 
B

Bob Barrows [MVP]

Just1Coder said:
I have the following function that is to import HTML data from a URL
to a MS-SQL table:

function gethtml(str)
'on error resume next
dim xmlhttp
set xmlhttp = Server.CreateObject("MSXML2.ServerXMLHTTP")
xmlhttp.open "GET", str, false
xmlhttp.send
newcontent = trim(xmlhttp.responseText)
if err.number <> 0 then
newcontent = "Error Retrieving URL, Please try again."
end if
set xmlhttp = nothing
' response.write ("<xmp>")
response.write (newcontent)
' response.write ("</xmp>")
end function

Works almost perfectly ... the URL's HTML is sucked in but the
whitespace is converted to ?'s.

You should have started your own thread instead of replying to this one.

Your problem is the lack of:
Response.ContentType = "text/xml"

Bob Barrows
 
J

Just1Coder

Thanks Bob.
You should have started your own thread instead of replying to this one.

Your problem is the lack of:
Response.ContentType = "text/xml"

Bob Barrows
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top