What do "first", "last" and "all" mean in --transaction on rt-crontool?

I’ve taken a look at the RT Book, the rt-crontool docs
rt-crontool - RT 5.0.3 Documentation - Best Practical and the Wikia
article http://requesttracker.wikia.com/wiki/UseRtCrontool and haven’t
been able to find an explanation of what exactly the transaction options
mean and control.

They’re not related to database-level transactions since RT doesn’t make
use of them.

I did some reading of the code and I’d like to confirm that my
understanding of what I see is accurate.

It looks like --transaction picks an existing transaction to set as
the context of the cronjob. ‘first’ for the tx that created the ticket,
‘last’ for the most recent ticket, or ‘all’ to select all transactions
on the ticket.

process(…) is called on each transaction found. It tests the condition
against the transaction and bails out if the condition doesn’t match.
Otherwise, prepare the action with the specified argument and if prepare
succeeds, commit it.

So basically, rt-crontool --transaction all will apply the action to
every tx on the scrip if the condition matches the tx; ‘last’ on the
most recent tx and ‘first’ on the first tx on the ticket. It’s not the
first/last tx that matches the condition; the transaction is picked and
THEN the condition is applied to decide whether an action should be taken.

It looks like all this is designed to have rt-crontool “piggy-back” on
existing transactions, which makes sense in that you don’t want to
create a new transaction for each run, especially when you might not do
anything. It’s a bit confusing when you’re doing things that don’t
really care about a particular transaction though.

–transaction-type looks like it refers to the Transaction.Type field,
with values like:

DelWatcher
SystemError
Create
AddLink
DeleteLink
Enabled
Comment
ResolveReminder
Forward Transaction
Set
Status
AddWatcher
CustomField
Disabled
CommentEmailRecord
Correspond
EmailRecord
AddReminder

so you could write:

–transaction last --transaction-type Comment

to find the most recent Comment on each ticket and, if one exists, apply
the Action to that transaction.

I’m a little puzzled by the way crontool doesn’t seem to have the
ability to create a new transaction for matching tickets. I guess the
action code is supposed to do that if a new transaction is required, eg
when adding a Comment to a ticket.

Some actions and conditions don’t require a transaction context, and for
those no --transaction should be specified; there’s an implicit
“–transaction none” where “undef” is passed as the transaction to act
on in process(…) .

This can result in unexpected effects, like sending mail in the name of
the person who last did something on the ticket, so it’s best to avoid
specifying a transaction unless you know you need one and one makes
sense in that context.

For example, if you invoke RT::Action::SendEmail, it’ll use the
transaction in GetFriendlyName to get the creator of the current
transaction and from it, the friendlyname. Same with SetReturnAddress.

It might be worth elaborating on this a little more in the documentation
and/or book. Feel free to use any of the above.

Craig Ringer http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

They’re not related to database-level transactions since RT doesn’t make
use of them.

This is wrong. RT does make use of DB transactions. grep for
BeginTransaction and/or Rollback.

It looks like --transaction picks an existing transaction to set as
the context of the cronjob. ‘first’ for the tx that created the ticket,
‘last’ for the most recent ticket, or ‘all’ to select all transactions
on the ticket.

[snip lots more]

Yes, that all sounds about right without verifying myself.

I’m a little puzzled by the way crontool doesn’t seem to have the
ability to create a new transaction for matching tickets. I guess the
action code is supposed to do that if a new transaction is required, eg
when adding a Comment to a ticket.

rt-crontool can create new transactions by using the normal RT actions,
just as you describe. I’m not sure why it seems odd to you.

crontool is fundamentally a way to run scrip conditions/actions over a
batch of tickets/transactions on a time-based trigger rather than solely
event-based.

Some actions and conditions don’t require a transaction context, and for
those no --transaction should be specified; there’s an implicit
“–transaction none” where “undef” is passed as the transaction to act
on in process(…) .

This can result in unexpected effects, like sending mail in the name of
the person who last did something on the ticket, so it’s best to avoid
specifying a transaction unless you know you need one and one makes
sense in that context.

For example, if you invoke RT::Action::SendEmail, it’ll use the
transaction in GetFriendlyName to get the creator of the current
transaction and from it, the friendlyname. Same with SetReturnAddress.

FWIW, the Notify* subclasses are generally much more useful than the
SendEmail action directly.

It might be worth elaborating on this a little more in the documentation
and/or book. Feel free to use any of the above.

As is, the above isn’t really suitable for pasting into the usage doc
for rt-crontool. A doc patch based on the above that fits with the rest
of the doc would be appreciated, though.

Thomas

It might be worth elaborating on this a little more in the documentation
and/or book. Feel free to use any of the above.

We have a draft that touches on the transactions at the end:

https://github.com/bestpractical/rt/blob/4.0/add-rt-crontool-docs/docs/automating_rt.pod

It’s not exhaustive, but does cover the basics.