preventing transaction rollback
I have a section of code that I want to have run only once during a request. It mails out some information about the request. I want only one email per request even if a conflict occurs during the request. I am having no luck eliminating duplicate emails. I have tried this a few different ways now, but currently my code looks something like this: def theFunction(self,REQUEST): "docstring" ...do some stuff... get_transaction().commit() try: ...send the email... get_transaction().commit() except: pass ...do some more stuff... return self.return_page_template(REQUEST) I thought that this try block with a commit() would isolate the send mail code in its own transaction, and then catch any conflict exception and ignore it. But I am still getting multiple emails per transaction when multiple requests happen at the same time and conflicts occur. How can I isolate a part of the code so that it can never roll back and execute again? --Sean
Use MailDropHost. It ties mail delivery to the transaction system of Zope. -aj --On Sonntag, 19. September 2004 3:38 Uhr -0400 Sean Hastings <whysean@softhome.net> wrote:
I have a section of code that I want to have run only once during a request. It mails out some information about the request. I want only one email per request even if a conflict occurs during the request. I am having no luck eliminating duplicate emails. I have tried this a few different ways now, but currently my code looks something like this:
def theFunction(self,REQUEST): "docstring" ...do some stuff... get_transaction().commit() try: ...send the email... get_transaction().commit() except: pass ...do some more stuff... return self.return_page_template(REQUEST)
I thought that this try block with a commit() would isolate the send mail code in its own transaction, and then catch any conflict exception and ignore it. But I am still getting multiple emails per transaction when multiple requests happen at the same time and conflicts occur.
How can I isolate a part of the code so that it can never roll back and execute again?
--Sean
_______________________________________________ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
Thank you very very much. MaildropHost was exactly what I needed - it is working great - both preventing duplicate mails, and speeding up the execution of my transactions quite considerably so that I am not getting nearly as many of the conflicts that were vastly slowing my application, and causing the duplicate emails to begin with. You have been very helpful to me on a number of occasions, both in answering my questions, and in the answers you have given to questions that I have found in the archives. Your helpfulness is very much appreciated! --Sean
-----Original Message----- From: Andreas Jung [mailto:lists@andreas-jung.com] Sent: Sunday, September 19, 2004 3:43 AM To: Sean Hastings; zope@zope.org Subject: Re: [Zope] preventing transaction rollback
Use MailDropHost. It ties mail delivery to the transaction system of Zope.
-aj
--On Sonntag, 19. September 2004 3:38 Uhr -0400 Sean Hastings <whysean@softhome.net> wrote:
I have a section of code that I want to have run only once during a request. It mails out some information about the request. I want only one email per request even if a conflict occurs during the request. I am having no luck eliminating duplicate emails. I have tried this a few different ways now, but currently my code looks something like this:
def theFunction(self,REQUEST): "docstring" ...do some stuff... get_transaction().commit() try: ...send the email... get_transaction().commit() except: pass ...do some more stuff... return self.return_page_template(REQUEST)
I thought that this try block with a commit() would isolate the send mail code in its own transaction, and then catch any conflict exception and ignore it. But I am still getting multiple emails per transaction when multiple requests happen at the same time and conflicts occur.
How can I isolate a part of the code so that it can never roll back and execute again?
--Sean
_______________________________________________ Zope maillist - Zope@zope.org http://mail.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://mail.zope.org/mailman/listinfo/zope-announce http://mail.zope.org/mailman/listinfo/zope-dev )
----- Original Message ----- From: "Sean Hastings" <whysean@softhome.net>
I have a section of code that I want to have run only once during a request. It mails out some information about the request. I want only one email per request even if a conflict occurs during the request. I am having no luck eliminating duplicate emails. I have tried this a few different ways now, but currently my code looks something like this:
def theFunction(self,REQUEST): "docstring" ...do some stuff... get_transaction().commit() try: ...send the email... get_transaction().commit() except: pass ...do some more stuff... return self.return_page_template(REQUEST)
I thought that this try block with a commit() would isolate the send mail code in its own transaction, and then catch any conflict exception and ignore it. But I am still getting multiple emails per transaction when multiple requests happen at the same time and conflicts occur.
An ugly solution: Create a variable (property field) on a temporary folder (contents stored in memory). When you send an email have the emailer routine load a unique identifier into the variable. In subsequent emails, check the contents of the variable before sending the email. As I said, 'ugly', but it should work! HTH Jonathan
Hi, Am So, den 19.09.2004 schrieb Jonathan Hobbs um 14:55:
...
I thought that this try block with a commit() would isolate the send mail code in its own transaction, and then catch any conflict exception and ignore it. But I am still getting multiple emails per transaction when multiple requests happen at the same time and conflicts occur.
An ugly solution:
Create a variable (property field) on a temporary folder (contents stored in memory). When you send an email have the emailer routine load a unique identifier into the variable. In subsequent emails, check the contents of the variable before sending the email.
As I said, 'ugly', but it should work!
Sorry. No. It does not work. Temporary storage is bound to the same transaction machinerie as all other zope storages. This means your stored value is wiped out when a transaction rollback is done. (in case of a conflict error for example). MailDropHost should be a solution as Andreas said. Regards Tino
MailDropHost looks like the right immediate solution to this problem. Thanks. However, I would like to understand, and resolve the conflicts if possible - Is there anyway to know if these are Read or Write Conflicts? When I look in the event.log - I just see lines that say: INFO(0) ZODB conflict error at /the_folder/the_object/theFunction Also, if I section off code as previously described, with get_transaction().commit, and still see that it is executing multiple times, does that mean that the code that is generating the conflict must be in that sub transaction? or is it possible for more than one subtransaction to get rolled back? If I can pin down the source of these conflicts, I hope to be able to eliminate or at least reduce them. Thank you very much for your help. --Sean
-----Original Message----- From: Tino Wildenhain [mailto:tino@wildenhain.de] Sent: Sunday, September 19, 2004 11:16 AM To: Jonathan Hobbs Cc: Sean Hastings; zope@zope.org Subject: Re: [Zope] preventing transaction rollback
Hi,
Am So, den 19.09.2004 schrieb Jonathan Hobbs um 14:55:
...
I thought that this try block with a commit() would isolate
the send mail
code in its own transaction, and then catch any conflict exception and ignore it. But I am still getting multiple emails per transaction when multiple requests happen at the same time and conflicts occur.
An ugly solution:
Create a variable (property field) on a temporary folder (contents stored in memory). When you send an email have the emailer routine load a unique identifier into the variable. In subsequent emails, check the contents of the variable before sending the email.
As I said, 'ugly', but it should work!
Sorry. No. It does not work. Temporary storage is bound to the same transaction machinerie as all other zope storages. This means your stored value is wiped out when a transaction rollback is done. (in case of a conflict error for example).
MailDropHost should be a solution as Andreas said.
Regards Tino
participants (4)
-
Andreas Jung -
Jonathan Hobbs -
Sean Hastings -
Tino Wildenhain