Problem

All MarkLogic requests run in either query or update mode, based on a static analysis of the code. The mode is important, because query requests are able to run without locking database content. Accidentally running in update mode is a common cause of requests running slower than expected.

Verify that a MarkLogic statement is running in query mode.

Solution

Applies to MarkLogic versions 7+

Place this snippet as early in the code path as you can to make sure it is executed before MarkLogic spends too much time on other parts of your request.

let $assert-query-mode as xs:unsignedLong := xdmp:request-timestamp()

If a request that includes this line is run as an update, then this error will be thrown:

XDMP-AS: (err:XPTY0004) let $assert-query-mode as xs:unsignedLong := xdmp:request-timestamp() -- Invalid coercion: () as xs:unsignedLong

Discussion

Sometimes MarkLogic’s static analysis may see something that triggers update mode, even if that was not the developer’s intent. The code in this recipe will throw an exception if it is run as an update, making it easy to notice the problem. Once this problem has been seen, find the code that caused the statement to run as an update. If the statement really should be running as an update, remove the assertion. If the update can be removed or isolated into an xdmp:invoke() call, do that to allow the statement to run as a query. Using this function, we can specify the “different-transaction” option, causing the update to be separated from the main request.

See the Transaction Type section of the Application Developer’s Guide for more information about query or update modes.

Note that we don’t need the same approach for Server-side JavaScript. With SJS, there is no static analysis; the developer must explicitly declare update mode.

It’s important to see that we can’t just call xdmp:request-timestamp() and get the same effect. The magic is in the as xs:unsignedLong — because that clause is present, MarkLogic will expect the value to be an unsigned long, or convertible to one. If the code returns the empty sequence, the conversion can’t happen, and the error is thrown.

The name is important too, in order to be self-documenting. What we don’t want to happen is that a developer runs into this exception and realizes that it can be “fixed” by removing the as xs:unsignedLong, or by changing it to as xs:unsignedLong? (making it optional). The presence of the word “assert” in the name provides a clue that we’re expecting something here, and silencing the message would be contrary to the original developer’s intent.

Learn More

Application Developer's Guide

Read the methodologies, concepts, and use cases related to application development in MarkLogic Server, with additional resources.

MarkLogic Developer Learning Track

Want to build that awesome app? Get off the ground quickly with the developer track, with instructor-led and self-paced courses.

Getting Started Video Tutorials for Developers

This series of short videos tutorials takes developers who are new to MarkLogic from download to data hub, fast.

This website uses cookies.

By continuing to use this website you are giving consent to cookies being used in accordance with the MarkLogic Privacy Statement.