duplicate keys, because of missing commit

Friday, 6 February 2015 · 3 messages · last reply 10 Feb 2015
CG
Christoph Gaukel6 Feb 2015 09:11 #
Hallo, the following xquery results in duplicate keys or missed updates, if we get two messages of the same person in one xml-document. All updates in the database are done at the end of the xquery and the reading inbetween gets the old state of the database. Is there a command to persist the actual state (like commit in sql)? If not, i need some help for my design, because i have no idea, how to get a stable processing. Kind regards, Christoph
(: Verarbeitung einer Bestandslieferung (1600).
:)
declare namespace xmeld="http://www.osci.de/xmeld21";
declare namespace kmeld="http://www.krz-swd.de/kmeld";
import module namespace kmeldFkt="http://www.krz-swd.de/kmeld/Fkt" at
"kmeldFkt.xq";
declare variable $file :=
"/home/christoph/Beruf/KRZ/Referenznachrichten/16.001.001.001a-1600.xml";

for $s in
doc($file)/xmeld:kirche.bestandslieferung.1600/xmeld:sachzusammenhang,
     $k in $s/xmeld:initialGeliefertesKirchenmitglied/xmeld:kirchenmitglied
   let $n   := $s/preceding-sibling::xmeld:nachrichtenkopf,
       $key := kmeldFkt:bildeIdMitglied($n, $k),
       $m_alt :=                        (: Mitglied im Bestand :)
collection("XMeldDB")/kmeld:XMeldDB/kmeld:personenbestand/kmeld:Mitglied[@ID
eq $key]
   let $m_neu :=
     if ($m_alt)
     then
       kmeldFkt:updateMitglied($m_alt, $k, $s, $n)
     else
       kmeldFkt:createMitglied($k, $s, $n)
   return
     if($m_alt)
     then
       replace node $m_alt with $m_neu
     else
       insert node $m_neu into
collection("XMeldDB")/kmeld:XMeldDB/kmeld:personenbestand
LK
Lukas Kircher6 Feb 2015 09:29 #
Hi Christoph,
Quoted text · Christoph Gaukel · 1 line
> the following xquery results in duplicate keys or missed updates, if we get two messages of the same person in one xml-document. All updates in the database are done at the end of the xquery and the reading inbetween gets the old state of the database.
Correct. This is dictated by the XQuery Update Facility and helps to bypass problems with dirty reads etc.
Quoted text · Christoph Gaukel · 1 line
> Is there a command to persist the actual state (like commit in sql)? If not, i need some help for my design, because i have no idea, how to get a stable processing.
No. There is no way to interfere with this mechanism. As a rule of thumb - to modify the same item or node within the same transaction several times calls for an aggregation of all changes beforehand and applying these as a single update. In your specific case, 'updateMitglied()’ should be called only once with parameters that lead to a consistent state of a ‘Mitglied’. With the information you gave us I assume this starts with a ‘group by person’ on the messages … Hope this helps, cheers, Lukas
LK
Lukas Kircher10 Feb 2015 16:09 #
Hi Christoph, I’m forwarding my answer (including yours) to the mailing list, as I think it is valuable input. I totally agree that the ‘equivalency' XQuery/transaction is very limiting. It sometimes leads to weird constructs trying to bypass the limitation. Quite often though the limitation is actually useful, as it forces you to re-write your query in a way that it fits a single transaction. Within a single transaction the compiler then has a lot more room for optimization etc.. I’m not defending our current approach here - there are cases where it causes real pain and affects overall application design. But I also think that, more often then not, a functional programming approach also solves the issue including all the benefits. After all, the concept of the XQuery Update Facility is true to the functional nature of XQuery, where variables are final (and cannot be changed once initiated). Extending XQuery with db:commit() kind of breaks these basic principles. I also think support for ‘chaining transactions’ would be beneficial, but maybe on another level (commands?). We write loads of production code in XQuery and this reflects just our experience - but I’d be happy to hear what others have to say. Cheers, Lukas
Quoted text · Christoph Gaukel · 10 lines
> On 09 Feb 2015, at 09:38, Christoph Gaukel <christoph.gaukel at gmx.de> wrote: > > Hi Lukas, > > thank you for your answer, but this is no good news. In my specific case, i see a variant to solve the problem. But i think, that the concept of transactions, which combines a number of updating commands into an atomic unit, is a good idea and it is a heavy load on the freedom of design if the only chance, to build transactions is the unit of an xquery. > > From my point of view, it would be an important improvement, if something like the commit of sql would be added to the xquery-language. If BaseX would introduce it as a specific extension like db:commit(), this would be great! > > Cheers, > Christoph

⚡Generated with XQuery