Do you need to set your variable to global ($$)? Did you try local ($)?
At your suggestion, I changed it to local, but the script behavior remains the same.
Is this script performed via a script trigger? If so, the script could be tripping it's own script trigger.
Also, your script will have issues if there are no related records to go to. You should add a test for the presence of related records.
And you can get the total of your records without go to related records nor a looping script. Since there is a relationship matching to these records, Sum ( Purpose::PurposeAmt ) will compute the total you are looping to compute in one step. A summary field defined in Purpose can also give you the same total.
It does feel like the script is being triggered twice. That's a clue. I had another script triggered by what I thought was a separate action. That script captured the purpose amount. It was somehow being triggered from within this script after the first pass. When I disabled that capture script, this script still loops through the whole set of records twice, but now it $$TransactionTotal get's zeroed out again on the second pass, so the total amount in $$TransactionTotal is correct. Better, but still hope to track down what is causing it to run again.
I'll check out the sum function. That is probably a better solution ultimately
Thanks also for the tip to test for the presence of related records!