MST = multi-statement transaction. By default MarkLogic's XQuery updates happen as single statements, without explicit commit or rollback.
http://blakeley.com/blogofile/2013/06/21/introduction-to-multi-statement-transactions/ -- Mike On 30 Jul 2014, at 04:13 , Retter, Adam (RBI-UK) <[email protected]> wrote: > Thank you Michael, I have monitored the transactions during running some > tests and they do appear to be short-lived. > > Can you explain what the acronym `MST` stands for please? And how would I > know if I am running in `MST update mode`? > > > > -----Original Message----- > From: [email protected] > [mailto:[email protected]] On Behalf Of Michael Blakeley > Sent: 29 July 2014 19:17 > To: MarkLogic Developer Discussion > Subject: Re: [MarkLogic Dev General] Transaction control and errors > > I'd expect rollback to be automatic if the transaction ends with an uncaught > error. You should only have to worry about rollback and commit if the > statement runs in MST update mode and completes successfully. > > To test that take a look at the host-status page in the admin UI. The third > table from the bottom shows active transactions on a host. It's normal to see > one on the Security database: that's your request for the host status page. > But if you see unexpected transaction entries and they hang around for > minutes, then you might have a problem with rollback. You can get the same > information from xdmp:host-status if you'd like to build tools around it. > > In passing, transactions will be atomic by default whether you call > xdmp:lock-for-update or not. You'd have to make an effort to avoid atomicity. > The reason to call xdmp:lock-for-update is to explicitly write-lock a URI, > either because you want to use a non-existent URI as a mutex or because you > want to lock a URI as early as possible to reduce the potential for deadlocks. > > -- Mike > > On 29 Jul 2014, at 08:50 , Retter, Adam (RBI-UK) <[email protected]> > wrote: > >> Hi there, >> >> We have a function that reads a collection of documents in the database, and >> then inserts N new documents into the collection depending on the results of >> the first read. We need this behaviour to be atomic, and so we explicitly >> take locks using xdmp:lock-for-update. This effectively forces the entire >> read and then conditional insert into a single threaded operation (which is >> fine). >> >> The problem is this, our function looks like this - >> >> declare private function load-entities( >> $entities as element()*, >> $etag-map as map:map, >> $entity-id as xs:string?, >> $is-orphaned-series-item-allowed as xs:boolean, >> $missing-etag-allowed as xs:boolean, >> $ignore-duplicate-updates as xs:boolean >> ) as element(store:etag-map) { >> >> let $_ := xdmp:set-transaction-mode("update") >> return >> let $entity-ids := fn:distinct-values($entities/c:id) >> let $_ := $entity-ids ! xdmp:lock-for-update(.) >> return >> let $etag-map := _load-entities($entities, $etag-map, >> $entity-id, $is-orphaned-series-item-allowed, $missing-etag-allowed, >> $ignore-duplicate-updates) >> return >> let $_ := xdmp:commit() >> return >> $etag-map >> }; >> >> This all appears to work fine... however reading the documentation >> http://docs.marklogic.com/6.0/xdmp:rollback it seems that we should >> explicitly rollback the transaction if we encounter an error. Our function >> is itself called from a REST function library which expects to capture >> errors (using catch) and then modify the http response code etc >> appropriately depending on the error. If we use xdmp:rollback in a try/catch >> within our function pasted above, this causes our REST API to break as there >> is no way to `bubble` the error up, because it appears that xdmp:rollback >> terminates the processing of the query immediately. For example we have >> tried this - >> >> declare private function load-entities( >> $entities as element()*, >> $etag-map as map:map, >> $entity-id as xs:string?, >> $is-orphaned-series-item-allowed as xs:boolean, >> $missing-etag-allowed as xs:boolean, >> $ignore-duplicate-updates as xs:boolean >> ) as element(store:etag-map) { >> >> let $_ := xdmp:set-transaction-mode("update") >> return >> try { >> >> let $entity-ids := fn:distinct-values($entities/c:id) >> let $_ := $entity-ids ! xdmp:lock-for-update(.) >> return >> let $etag-map := _load-entities($entities, $etag-map, >> $entity-id, $is-orphaned-series-item-allowed, $missing-etag-allowed, >> $ignore-duplicate-updates) >> return >> let $_ := xdmp:commit() >> return >> $etag-map >> } catch($e) { >> (xdmp:rollback(), >> xdmp:rethrow() >> ) >> } >> }; >> >> The problem being if we call xdmp:rollback before xdmp:rethow, it appears >> that rethow is never called so our REST API fails to see the error and just >> returns HTTP 200. Likewise if we call xdmp:rethrow before xdmp:rollback, it >> seems that xdmp:rollback is never called. I guess I kinda expected that >> behaviour... but how do we actually solve our problem then? >> How *bad* would it be to not actually call xdmp:rollback in terms of >> transactions being collected when they timeout? >> >> Please keep in mind that this is a large code-base and whilst it has some >> design issues, refactoring everything at present is not really an option. >> >> Cheers Adam. >> >> DISCLAIMER >> This message is intended only for the use of the person(s) ("Intended >> Recipient") to whom it is addressed. It may contain information, which is >> privileged and confidential. Accordingly any dissemination, distribution, >> copying or other use of this message or any of its content by any person >> other than the Intended Recipient may constitute a breach of civil or >> criminal law and is strictly prohibited. If you are not the Intended >> Recipient, please contact the sender as soon as possible. >> Reed Business Information Limited. Registered Office: Quadrant House, The >> Quadrant, Sutton, Surrey, SM2 5AS, UK. >> Registered in England under Company No. 151537 >> >> _______________________________________________ >> 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
