How to force an open transaction for test purposes - Forum - OpenEdge Development - Progress Community

How to force an open transaction for test purposes

 Forum

How to force an open transaction for test purposes

This question is answered

We had a situation where a client-server user has been working for a couple of hours with an open transaction.

After he finished he closed the application and everything was undone.

I would like to create a bad behaving procedure that leaves a transaction open while returning control to the caller.

This proves to be harder than I imagined,

I now have a persistent procedure that creates a record in the main block on a globally scoped buffer but this does not leave a transaction open.

I tried creating the record in internal procedures, doing excluive-find in an internal procedure

None of these actions leave the transaction op after the call finishes

Below is the code I have so far. I would have hoped this was sufficently bad  but  transaction is false

run devtools/transactiontrouble-l.p persistent.
run trouble_exclusivefind.
message "transaction" transaction.
 

block-level on error undo, throw.

define buffer global_CCECONV for CCECONV.
run cleanup_previous.
session:add-super-procedure(this-procedure). /* self-register as super procedure */

/*
find first global_CCECONV /* ensure scope is procedure-wide */
    where global_CCECONV.AP-NR = 0
      and global_CCECONV.CONV-CODE = this-procedure:file-name
    share-lock.*/
create global_CCECONV.
run trouble_starttransaction.

procedure cleanup_previous:

define variable lHandle as handle no-undo.
define variable lCount as integer no-undo.

do lCount = 1 to num-entries(session:super-procedures):
    lHandle = widget-handle(entry(lCount, session:super-procedures)).
    if lhandle:filename = this-procedure:filename
    then do:
        apply "close" to lHandle.
        delete procedure lHandle.
    end.
end.

end procedure.

procedure trouble_exclusivefind:

find first global_CCECONV
    where global_CCECONV.AP-NR = 0
      and global_CCECONV.CONV-CODE = this-procedure:file-name
    exclusive-lock.

end procedure.


/**
 * Purpose: Start a transaction and leave it open
 * Notes:
 *
 */
procedure trouble_starttransaction:

    on write of cceconv old OLD-cceconv override  do: end.
    assign
        global_CCECONV.AP-NR        = 0
        global_CCECONV.CMP-ID       = next-value(CCECONV-ID)
        global_CCECONV.CRE-WHO      = userid("LISA")
        global_CCECONV.CRE-DAT      = today
        global_CCECONV.CONV-CODE    = this-procedure:file-name
        global_CCECONV.CONV-CCE-V   = ?
        global_CCECONV.CRE-TIME     = time
        global_CCECONV.CONV-TYPE    = "trouble"
    .

end procedure.


/**
 * Purpose: Undo the transaction
 * Notes:
 * @param parameter1 Description
 * @return
 */
procedure trouble_undotransaction:


end procedure.

Has somebody created such a procedure that he/she can share ?

Any hints on how to cause an open transaction ?

Verified Answer
  • Transactions should end when the iteration of the block they are scoped to ends.

    Given that, it shouldn't be possible for a (sub)transaction started in a callee to still be active when control gets back to the caller -> the callee and any blocks it contains will have moved out of scope at that point.

    (Side note: If the buffers used in a tranaction do remain in scope when the transaction ends, locked records won't be released; they'll move to downgraded share-locks instead. That can cause other issues.)

    Whatever the issue was, it's most likely that the bad transaction was opened earlier on the call stack than the program the user was actually using to interact with the data.

All Replies
  • Hi Carl,
     
    Try something like this:
     
    /* test.p */
     
    run procx in this-procedure.
     
    procedure procx:
        find first customer exclusive-lock.
    end procedure.
     
     
    Brian Maher
    Principal Engineer, Technical Support
    Progress
    Progress
    14 Oak Park | Bedford, MA 01730 | USA
    phone
    781-280-3075
    Twitter
    Facebook
    LinkedIn
    Google+
     
     

  • Transactions should end when the iteration of the block they are scoped to ends.

    Given that, it shouldn't be possible for a (sub)transaction started in a callee to still be active when control gets back to the caller -> the callee and any blocks it contains will have moved out of scope at that point.

    (Side note: If the buffers used in a tranaction do remain in scope when the transaction ends, locked records won't be released; they'll move to downgraded share-locks instead. That can cause other issues.)

    Whatever the issue was, it's most likely that the bad transaction was opened earlier on the call stack than the program the user was actually using to interact with the data.

  • > On Aug 2, 2019, at 5:10 AM, cverbiest wrote:

    >

    > Any hints on how to cause an open transaction ?

    >

    >

    >

    >

    in the main procedure, update a record, then call a sub-program that does more stuff and contains code that waits for user input. then user goes on vacation.

    main.p:

    define buffer c for customer.

    find c 1.

    c.postal-code = 12345.

    run sub.p

    sub.p:

    find last customer.

    update customer.

  • I was hoping there was a way to test this without causing a transaction higher in the call stack.

    But I'm glad there isn't.

    Thanks to all who replied