I recommend that you revisit that requirement, because it conflicts with best
practices for MarkLogic Server. With MarkLogic Server the best practice is to
keep documents and their metadata in the same database. The database
architecture is optimized to store many different document types in one
database.
There are three common ways of storing metadata in MarkLogic:
(a) Inline: this is the most common approach, because it is optimal for
querying of content and metadata without joins. But it is not suitable for BLOB
or CLOB content. Very large documents may also benefit from (b) or (c). This is
typically used when the relationship between documents and metadata is
one-to-one, and common queries of document and metadata will be important.
<document-root>
<metadata>
<!-- metadata goes here -->
</metadata.
<body>
<!-- main document goes here -->
</body>
</document-root>
You can name the elements whatever you like, of course.
(b) Properties: see http://docs.marklogic.com/guide/app-dev/properties for
details. This is non-optimal for querying metadata and content at the same
time. However it works well for CLOB and BLOB content, and is also used by CPF
to maintain workflow state. This is typically used when the relationship
between documents and metadata is one-to-one, and joins are rare.
(c) Separate documents: for example the main document might be /a/b/c/main.xml
and the metadata might be /a/b/c/meta.xml - or whatever convention you like. As
with (b), queries checking both content and metadata constraints require joins.
This is typically used when the relationship between documents and metadata is
many-to-one and joins are rare.
-- Mike
On 27 Feb 2013, at 03:36 , Jonna Marry <[email protected]> wrote:
> Hi,
>
> My requirement is to load 2 different documents(actual document and metadata
> document) in two different Database. We have a condition that if any one of
> the insert operation fails we need to rollback the entire transaction.(i.e.
> Need to revoke the last insert operation)
>
> ML version 5.0
> Example:
>
> Consider a main.xqy which will invoke a file "check.xqy".
> main.xqy
>
> xdmp:invoke( ("/check.xqy")), (
> xs:QName("input"), xdmp:quote($input),
> ),())
>
>
> check.xqy - We have used invoke statements to call "insertFirst.xqy" and
> "insertSecond.xqy" to insert the documents. Database in which these documents
> should get loaded will be mentioned in these "insertFirst" and insertSecond"
> xqy files.
>
> let $res1 := xdmp:invoke( ("/insertFirst.xqy")), (
> xs:QName("input"), $input,
> ),())
> return if(fn:not( fn:contains( $res1, "Error"))) then
>
> let $res2 = xdmp:invoke( ("/insertSecond.xqy")), (
> xs:QName("input"), $input,
> ),())
> return if(fn:not( fn:contains( $res2, "Error"))) then
> (: "Need to rollback the insertOne changes" :)
> xdmp:rollback()
>
> else
> ( :"Success and commit both insert operation" :)
> xdmp:commit()
> else
> ( "Throw exception")
>
> We are unable to commit/rollback the entire transaction. we tried "declare
> option xdmp:transaction-mode "update";" or
> "<isolation>same-statement</isolation> " options.
>
> Added "xdmp:commit()" or "xdmp:rollback" based on the success/failure , but
> after these commit/rollback statements , we couldn't able to process any
> other statements in the xqy file.
>
> Please suggest how to handle this scenario to rollback the transaction.
>
> Regards,
> Jonna
>
>
> On Mon, Feb 25, 2013 at 12:53 PM, Michael Blakeley <[email protected]> wrote:
> Which version of the server are you using?
>
> You haven't said what's going wrong. What's the problem? If you have an error
> message it's always a good idea to paste that in.
>
> I suspect that you're seeing something like "XDMP-MULTIDBSTMT: Cannot process
> different-database requests with same-statement isolation". If so the error
> message says it all: you can't update two different databases in the same
> statement. This is covered at
> http://docs.marklogic.com/guide/app-dev/transactions#id_24388
>
> > You may not use same-statement isolation when using the database option of
> > xdmp:eval orxdmp:invoke to specify a different database than the database
> > in the calling statement's context. If your eval/invoke code needs to use a
> > different database, use different-transaction isolation.
>
> Using different-transaction isolation means that you're really committing two
> transactions, each atomic in its own database but discrete from each other.
> You can try to structure your update sequence so that the first update will
> be the sensitive one, and will automatically keep the second one from running
> if it throws an error. But I can't think of a way to update two different
> databases in a single ACID transaction. I don't think multi-statement
> transactions will help. You could try XA, I suppose, but that gets
> complicated quite quickly and I wouldn't recommend it.
>
> At this point I would back up and revisit the design. Why do you want to
> update two databases at once? If two documents need to participate in a
> transaction, maybe they should be in the same database. Then you wouldn't
> need any invokes at all.
>
> In passing, the xdmp:quote($input) is probably unnecessary. I imagine you
> added that in an attempt to work around XDMP-MULTIDBSTMT, but it won't.
>
> -- Mike
>
> On 25 Feb 2013, at 07:50 , Jonna Marry <[email protected]> wrote:
>
> > Hi,
> >
> > I have a scenario to insert 2 different documents in 2 different databases
> > in single transaction.If either one fails, I need to roll back the insert
> > operation.
> > I tried using "xdmp:transaction-mode" and
> > "<isolation>same-statement</isolation> " options. It would be helpful if
> > I get some suggestion to resolve this issue.
> >
> >
> > xquery version "1.0-ml";
> > declare option xdmp:transaction-mode "update";
> >
> > let $_1 := xdmp:invoke( ("/aa.xqy")),
> > (
> > xs:QName("input"),
> > xdmp:quote($input),
> >
> > ),
> > <options xmlns="xdmp:eval">
> >
> > <isolation>same-statement</isolation>
> >
> > <database>{xdmp:database("test1")}</database>
> > </options>
> > )
> > let $_2 := xdmp:invoke( ("/aa.xqy")),
> > (
> > xs:QName("input"),
> > xdmp:quote($input),
> >
> > ),
> > <options xmlns="xdmp:eval">
> >
> > <isolation>same-statement</isolation>
> >
> > <database>{xdmp:database("test2")}</database>
> > </options>
> > )
> > return "success"
> > note :
> >
> > Regards,
> > Jonna.
> > _______________________________________________
> > General mailing list
> > [email protected]
> > http://developer.marklogic.com/mailman/listinfo/general
>
> _______________________________________________
> General mailing list
> [email protected]
> http://developer.marklogic.com/mailman/listinfo/general
>
> _______________________________________________
> General mailing list
> [email protected]
> http://developer.marklogic.com/mailman/listinfo/general
_______________________________________________
General mailing list
[email protected]
http://developer.marklogic.com/mailman/listinfo/general