[ZCM] [ZC] 2273/ 4 Comment "ConflictError causes multiple Emails, multiple external database calls..."

"Collector: Zope Bugs, Features, and Patches ..." <[email protected]> Mon, 05 Feb 2007 03:27:45 -0500
Newsgroups gmane.comp.web.zope.devel.collector-monitor
Message-ID <[email protected]>
Issue #2273 Update (Comment) "ConflictError causes multiple Emails, multiple external database calls..."
 Status Rejected, Zope/feature+solution medium
To followup, visit:
  http://www.zope.org/Collectors/Zope/2273

==============================================================
= Comment - Entry #4 by chrisw on Feb 5, 2007 3:27 am

To be clear:

sending email - use MailDropHost or zope.sendmail. The former scales better as mail sending is done in a seperate process.

queuing a print job - this isn't a "usual" requirement, so you'd need to write your own transactional data manager for this.

external relational database - all the DA's I've used have been transactional. If you've found a database where that isn't the case, switch databases or switch DA's ;-)
________________________________________
= Reject - Entry #3 by philikon on Feb 3, 2007 10:14 am

 Status: Pending => Rejected

The canonical way to ensure that something is carried out only when a transaction is committed is to write a data manager (see transaction.interfaces.IDataManager).

The zope.sendmail package uses such a datamanager to make the sending of emails transaction-aware. See http://svn.zope.org/Zope3/trunk/src/zope/sendmail/delivery.py?rev=67630&view=auto for the code. Note that you can use zope.sendmail in Zope 2 today (in Zope 2.8 and 2.9 it's called zope.app.mail).

I'm surprised MailHost isn't transaction aware. If you'd like to make it, please submit a patch that uses a datamanager. Modifications to the transaction package aren't needed. And, like Andreas says, please provide automated tests for your modifications (we don't accept untested code).

Lastly, if you submit patches that aren't bugfixes (I'd say this is a feature, not a bugfix), please provide then against the latest Zope 2 trunk (svn co svn://svn.zope.org/repos/main/Zope/trunk). The output of 'svn diff' will be sufficient.
________________________________________
= Comment - Entry #2 by ajung on Feb 3, 2007 3:36 am

Interesting idea. However some unittests are required for inclusion of the patch
________________________________________
= Request - Entry #1 by marc_mengel on Feb 2, 2007 3:31 pm


Uploaded:  "patch"
 - http://www.zope.org/Collectors/Zope/2273/patch/view
When a Zope object does something which is visible outside of the ZODB (i.e. sending email, queuing a print job, updating an external relational database, etc.) and then does something else that generates a ConflictError, Zope abort()s the transaction and re-runs the code, this then causes the externally visible action to happen AGAIN (i.e. two (or three) email's get sent, two (or three) database records get added...)

This patch builds an afterCommitHook queue, like the beforeCommitHook queue that exists, so you can queue up those actions, and run them after (and only if) the commit succeeds.  The MailHost object is patched to do so.
==============================================================