Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

perl script & mysql after insert trigger

by vxp (Pilgrim)
on Nov 26, 2010 at 19:27 UTC ( [id://873916]=perlquestion: print w/replies, xml ) Need Help??

vxp has asked for the wisdom of the Perl Monks concerning the following question:

Hi. I realize this may not be the right place to ask, as it's a mysql trigger related question.. but there's some perl here too! Please see if you can spot something silly here, as I am running out of ideas with this issue here.. here's what's up: it seems like the "after insert" trigger gets triggered before the values get inserted into the new row in table. here's my trigger:
DELIMITER $$ CREATE TRIGGER `new_email` AFTER INSERT ON `dbmail_subjectfield` FOR EACH ROW BEGIN SET @exec_var = sys_exec(CONCAT('/bin/sh /home/vxp/veng/bin/deadweight + ', NEW.id)); END; $$ DELIMITER ;
the "deadweight" is just that: a deadweight shell script that adds 20 (!) seconds to the execution via sleep, then executes a perl script that queries that new row, the one that triggered the trigger/deadweight, for values:
[vxp@vader bin]$ cat deadweight #!/bin/sh echo `date` >> /home/vxp/veng/deadweight.log echo "Sleeping for 20 seconds" >> /home/vxp/veng/deadweight.log sleep 20 echo `date` >> /home/vxp/veng/deadweight.log echo "executing /home/vxp/veng/bin/email_retrieve.pl $1" >> /home/vxp/ +veng/deadweight.log /home/vxp/veng/bin/email_retrieve.pl $1 [vxp@vader bin]$
the sequence of events is thus as follows: 1. a new row gets inserted, which triggers deadweight and passes the ID of the new record to it 2. deadweight sleeps for 20 seconds, and calls a perl script that queries that ID for values 3. perl script gets 0 rows. if I query that new row manually (as in, not via the trigger), by just executing my perl script and passing it the new row's id, I get results, not 0 rows. what's the deal here? how do I trigger my script AFTER the values have been successfully inserted into the new row? Any help highly appreciated

Replies are listed 'Best First'.
Re: perl script & mysql after insert trigger
by Illuminatus (Curate) on Nov 26, 2010 at 23:13 UTC
    something silly spotted here...

    If you are using transactions, then this is most likely your problem. You are in a catch-22. The trigger fires as part of the transaction, but the data is not there until the commit. The general concept behind triggers is to perform additional table-specific operations (regardless of individual sql operation) that can also be rolled-back if necessary. You could create another table, ie email_retrieve, with a single column containing the row-id. Your trigger would insert into that table instead of invoking 'deadweight'. Then, all you have to do is periodically scan this table for entries, call your script, and remove the entries.

    fnord

      I see.

      I went around the problem in my usual proctology-like way.

      instead of:

      SET @exec_var = sys_exec(CONCAT('/usr/bin/perl /home/vxp/veng/bin/emai +l_retrieve.pl ', NEW.id));
      I now have:
      SET @exec_var = sys_exec(CONCAT('/usr/bin/perl /home/vxp/veng/bin/emai +l_retrieve.pl ', NEW.id, ' &'));

      So the trigger places my script in the background now ("&"). That lets it "return" immedeately, mysql finishes the commit, and the script gets its values.

      It's a through-the-ass solution but it seems to work for my purposes :)

Re: perl script & mysql after insert trigger
by pajout (Curate) on Nov 27, 2010 at 09:49 UTC
    I totally agree with Illuminatus, just adding some ideas:

    - If it is possible and not very very complex, postprocess inserted row directly in trigger body. All happens in the transaction, so when something fails, row is not inserted - nothing happens, and you are not in the half of the processing.

    - If such processing is impossible or too complex, simply insert the row without trigger, but dedicate one column for the state="NEW", for instance. Let you have (perl :>) process (or more than one), which selects new rows, process them and changes their state to "DONE". Be aware of race conditions if you have more than one process which does the work - you can lock processed rows, but I am not expert of MySQL. Think about necessary states for your solution...

    In other words, keep whole processing in transaction, if you can. Otherwise, use a chain of db transactions, which establishes one "logical" transaction.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://873916]
Approved by Marshall
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (4)
As of 2024-04-23 16:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found