Hi Neil,
Since you did not include your code, it is hard to tell exactly what is
happening in your application. But yes, there are nice ways to accomplish what
you want. MarkLogic is fully transactional, so it is designed to do this type
of thing.
There are a number of ways to do this. If you use xdmp:invoke, that invokes an
XQuery module that runs in a new transaction, and the calling program waits for
it to complete and return its results before continuing. Here is an example of
how you might accomplish what you talked about using xdmp:invoke.
1) Create a simple document as follows:
xdmp:document-insert("/increment.xml", <foo>1</foo>)
2) Create an xqy module in the app server root called read.xqy with the
following content:
doc("/increment.xml")
3) Create another xqy module in the app server root called test.xqy with the
following content:
let $x := doc("/increment.xml")
let $y := <foo>{$x/foo/text() + 1}</foo>
return
xdmp:document-insert("/increment.xml", $y)
4) Now run the following XQuery:
doc("/increment.xml"),
xdmp:invoke("/test.xqy"),
xdmp:invoke("/read.xqy")
It will return 2 nodes:
<foo>1</foo>
<foo>2</foo>
If you run it again, it will return the following 2 nodes:
<foo>2</foo>
<foo>3</foo>
And so on. To understand what is happening here, look at the XQuery request
that prints the old version of the document followed by the new version:
doc("/increment.xml"),
xdmp:invoke("/test.xqy"),
xdmp:invoke("/read.xqy")
First, it reads the version of the document at the timestamp in which the query
runs. The first time we run this, that gives the value of 1 that we initially
created the document with. Next, it invokes, as a separate transaction,
test.xqy, which increments the value by 1 in the document stored in the
database. Finally, as yet another transaction, it invokes read.xqy, which
reads the document at the new timestamp. Because the calling query waits for
xdmp:invoke to complete before continuing with its processing, the transaction
that invokes the read.xqy module will see the new version of the document.
Remember, xdmp:invoke returns whatever the invoked module returns. In the case
of the update, it returns the empty sequence. In the case of the read, it
returns the document.
Now if we ran the query again and put another doc("/increment.xml") at the end
as follows:
doc("/increment.xml"),
xdmp:invoke("/test.xqy"),
xdmp:invoke("/read.xqy"),
doc("/increment.xml")
We get the following:
<foo>3</foo>
<foo>4</foo>
<foo>3</foo>
The reason the last foo has the value of 3 is that that entire request runs at
the same timestamp, and so it sees a consistent view of the database. The
value of 4 came from another transaction, which sees the view of the database
at its own (newer) timestamp.
The Developer's Guide has a more formal overview of how transactions work in
MarkLogic Server.
Hopefully this will help you understand what is going on on your system.
-Danny
From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of Neil Bradley
Sent: Thursday, November 29, 2007 10:07 AM
To: 'General Mark Logic Developer Discussion'; 'General XQZone Discussion'
Subject: [MarkLogic Dev General] Needing to wait for document update
Hi,
I have an interactive application that lets users build and save complex
queries as XML files in the database. When the user adds (or deletes) a
parameter to one of the queries, I update the XML file, then re-direct to the
code that reads the XML file and presents the updated query.
Sometimes, the update is not seen and I have to refresh the browser window to
see it. I assume that this is because the XML document is not actually updated
in time for the next request, so the older version is seen instead.
Is there an elegant way to solve this?
I already tried putting the update and the read in separate transaction, but
that did not help. I really need to wait until the XML file is definitely
updated.
Of course, I could increment a counter in the XML file, and reject reading it
until I detect a higher number than the value it had before the update, but
that seems a real kludge.
Any better ideas?
Neil.
_______________________________________________
General mailing list
[email protected]
http://xqzone.com/mailman/listinfo/general