Hi Jeff, What do you mean by "linear order of operations"? I do not get any timeouts.
I begin the transaction before the pseudo code above, and attempt to commit the transaction after the pseudo code - it is the commit that causes the ConcurrentModification operation. I am quite sure I do not start any nested transactions, as my logic only begins/commits/rollback transactions when a servlet is invoked. I did try starting a nested transaction for the part of the pseudo code that sends mail to the external system and updates statusses accordingly, but that did not work either, so I went back to the original code with only one transaction. Thanks, -Louise Den lørdag den 25. marts 2017 kl. 19.14.22 UTC+1 skrev Jeff Schnitzer: > > That does not sound correct. > > If you have a linear order of operations in the same transaction (or > entirely without transactions), you should never see concurrent > modification exception. Timeouts are a different matter. > > To the OP: Where are you transaction boundaries? Are you accidentally > starting a new transaction “inside” an outer transaction and modifying the > same entity as the outer transaction? That will guarantee CME every time. > > Jeff > > On Fri, Mar 24, 2017 at 4:02 PM, 'Adam (Cloud Platform Support)' via > Google App Engine <[email protected] <javascript:>> wrote: > >> A great article that explains this is 'Timeouts due to write contention >> <https://cloud.google.com/appengine/articles/handling_datastore_errors#timeouts-due-to-write-contention> >> ': >> >> *Writes to a single entity group are serialized by the App Engine >>> datastore, and thus there's a limit on how quickly you can update one >>> entity group. In general, this works out to somewhere between 1 and 5 >>> updates per second.* >> >> >> Writing to the same entity twice successively is enough to cause a >> ConcurrentModificationException. Strategies to avoid this are discussed in >> 'Avoiding >> datastore contention >> <https://cloud.google.com/appengine/articles/scaling/contention>'. >> >> On Friday, March 24, 2017 at 3:18:28 AM UTC-4, Louise Elmose Hedegaard >> wrote: >>> >>> Hi, >>> >>> In my app I have the following logic (pseudoCode): >>> >>> List<NonSentMails> nonSentMails= getNonSentMails();//1) datastore read >>> >>> List<NonSentMails> sendNow = new ArrayList<NonSentMails>(); >>> for each nonSentMail in nonSentMails >>> if (sendNow(nonSentMail)){ >>> sendNow.add(nonSentMail); >>> } >>> >>> for each nonSentMail in sendNow >>> SentStatus sentStatus = sendMailViaRestApi(); >>> create maillog in datastore with sent status//2) datastore write - >>> new entry >>> nonSentMail.setSentStatus(sentStatus); >>> >>> update(sendNow) //3) datastore write >>> >>> >>> When comitting the above I get: >>> java.util.ConcurrentModificationException: too much contention on these >>> datastore entities. please try again. >>> >>> This is a problem, as the operation is not idempotent - when I send a >>> mail via a REST API the mail is sent immediately, and I want the status of >>> my maillog and NonSentMail objects to reflect this. >>> >>> I do not understand why this error occurs. >>> There are only three operations on the datastore: >>> 1) The initial read of non sent mails >>> 2) The creation of new mail log entries >>> 3) The update of the status of non sent mails >>> >>> 2) should never lead to ConcurrentModificationException as far as I >>> understand it. 1) and 3) operates on the same entities, but 1) only reads, >>> so I cannot see any problem here either. >>> Furthermore there is currently only one user of my app, so there should >>> be no other threads accessing the data. >>> Note that the elements in sendNow might have the same parents, but again >>> I do not believe this should be a problem? >>> >>> Can you please help me understand why the above code can lead to a >>> ConcurrentModificationException? >>> >>> Thanks, >>> -Lull >>> >>> -- >> You received this message because you are subscribed to the Google Groups >> "Google App Engine" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected] <javascript:>. >> To post to this group, send email to [email protected] >> <javascript:>. >> Visit this group at https://groups.google.com/group/google-appengine. >> To view this discussion on the web visit >> https://groups.google.com/d/msgid/google-appengine/aec47937-549f-4de2-899d-b59da5163ad8%40googlegroups.com >> >> <https://groups.google.com/d/msgid/google-appengine/aec47937-549f-4de2-899d-b59da5163ad8%40googlegroups.com?utm_medium=email&utm_source=footer> >> . >> >> For more options, visit https://groups.google.com/d/optout. >> > > -- You received this message because you are subscribed to the Google Groups "Google App Engine" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at https://groups.google.com/group/google-appengine. To view this discussion on the web visit https://groups.google.com/d/msgid/google-appengine/d18d2553-f8fa-4314-9232-848a4854785a%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
