On Nov 17, 2003, at 7:20 AM, Gary Murphy wrote:

Ilja:
To truly benefit from transaction control you really need to advantage, not just by grouping DML statements, but also by use of the "rollback" statement
in the case of an individual statement's failure.

Correct, although you don't actually need to rollback a transaction postgres if there's a error reported from the database, as it puts the entire transaction into an abort state. You can (effectively) either commit or rollback to clear that transaction and start another one. Of course, you really want to be trapping for that sort of error so that you can report back to the outer levels.

Eric's first try is a quick and dirty method which manages to bundle
together the three insert statements which are used for inserting data into the database, which will definitely help performance and is definitely an
improvement.

That was quick and dirty, and (iirc) it's not exactly right. It certainly doesn't deal with all of the possible quota issues. I was trying to get something that was both simple enough to be easily coded and explained and enough of a performance win that it's clearly a direction to go.

I've also been thinking about the quotas a bit, especially not worrying about them if there's no quota on the account. But for those cases where there is one, It would be _really_ nice to be able to figure out message size and quota applicability before a potentially large message was added to the database, at least from a code path point of view. It would make the transactioning much more of a catch for database problems than the rollback bits that are required for a quota miss now.

There are really a few possibilities: If the message size is small, then it isn't that bad to read it into memory. Either it's going to work, or you're already over quota. For large messages, it's more dangerous to read into memory, especially depending on the largest message that is supported through the mta. Here if maxMessage < freeQuota, then quota is not an issue. It's only where maxMessage>freeQuota and maxMessage is too much ram to burn that there's a problem. I don't know of many systems where the max mail message size is over 10 megs.

The other possibilty is that if you look at is as softQuota = enteredQuota and hardQuota = enteredQuota+maxMessage, then you could just look to see if they're already over quota before the insert, just preventing any further messages past the one that went over. If that's coupled with reading in the entire message to get the size, then you already have all of the information for the uniqueid hash and the message size, so it's no longer an insert + update on the message table.

Best use concepts, however, dictate that transaction control
really belongs to the database level, not the application level. His is,
however, the "easiest" solution given the current code layout.

Indication of begin/end transactions need to be at the code level where you know that you're dealing with a set of changes that need to atomically happen. That could be calling a stored procedure so that one statement is issued with autocommit transactions, or it could be at the level that we have here. I will say that we shouldn't be issuing sql for begin/commit at that level.

I believe the correct solution, if it doesn't break one of the IMAP or POP3 RFC's is to call only one database function to completely manage a message insert when one is desired rather than depending upon an assorted number of
these.  Then transaction enable the function to respond correctly upon
inserts (batch them together) and or failures (rollback everything) if and
when they happen.

It depends on how much error reporting logic we want. It it's just pass/fail, then a transaction failing is fine. But with more fine grained deliveries, with multiple recipients on different quotas, it's possible for some to fail and some to succeed. Which is hard to do from within the database event horizon. (at least, on postgres. It's impossible on mysql). Pop should be nearly trivial to do with single statement update/deletes, there's some trickyness to imap that might prevent some of that.

Sorry if this is a bit of a brain dump, but I've had these things rattling around in my head for a while. Expect another one on the db_getmailbox function soon, since that's one place where my performance is hurting right now. ;>

eric

Reply via email to