"Version: 11.5, 11.6"
But the sample code uses // style comments (introduced in 11.6).... OK. But the real bummer is:
Call me a rookie, but an explicit transaction block on a NO-UNDO temp-table? I personally would rather use one method or another to scope the buffer TTObject to the internal procedures instead.
Architect of the SmartComponent Library and WinKit
Just letting you know we saw your post and will engage the author of the article. Thanks for starting the discussion.
> but an explicit transaction block on a NO-UNDO temp-table?
What is wrong with that?
> What are you expecting to UNDO?
I would expect that a transaction block commits the changes.
> In which way, would the code behave any different with/without those TRANSACTION blocks?
DEFINE TEMP-TABLE tt
FIELD f1 AS INTEGER INITIAL 0
FIELD f2 AS INTEGER INITIAL 0
INDEX f1 f1
INDEX f2 f2.
ASSIGN tt.f1 = 1.
MESSAGE CAN-FIND(FIRST tt WHERE tt.f2 EQ 0)
VIEW-AS ALERT-BOX INFO BUTTONS OK.
Sorry, I just forgot to specify NO-UNDO (I'm watching football in parallel ;-). But the result is the same.
We could explicitly add: ASSIGN tt.f2 = 0. but the index key will not be created until the end of transaction block. It might confuse a reader of the code.
This is my article. Thanks for the feedback. I'll remove 11.5 from the version info as I don't want to go back and change the comments. As for the NO-UNDO & DO TRANSACTION block, I know it isn't really needed but I prefer to write it that way as a safety net so that when (not if) people change the code they don't accidentally introduce a scoping issue. I've seen that happen too many times over the years. If the bit of extra code really bothers people I will consider removing it but for now I will leave it as it is.
I put locks on TTs and transactions around them to indicate my intent, and to have a consistent coding appearance across the code base. If a developer gets confused by that, one has to wonder what else they're getting wrong.
The problem is, that a developer reading only that internal procedure may assume that when the ASSIGN failes, the CREATE is undone. But it won't. Code should be easy to understand.
> a developer reading only that internal procedure may assume that when the ASSIGN failes, the CREATE is undone.
...while a developer SHOULD always assume that the CREATE is completed /only/ outside transaction block. It's especially important for UNDO temp-tables because in this case it's a programmer (not Progress) who is responsible for handling the errors (for example, the errors for the unique index keys). I saw many cases when programs had the problems just due to the lack of explicite transaction property of the blocks where temp-tables are created.
And for the same reasons mentioned by Tim Kuehn I specify the explicite locks (no-lock or exclusive-lock) for temp-tables. Though I understand it might confuse a reader.
> The explicit DO TRANSACTION shouts
I would re-word it as: programmer shouts: I guarantee there will be no errors inside the block.
ASSIGN TTObject.CreateLine = ILineNumber
TTObject.LogDateTime = SUBSTRING(CData, 2, 26)
TTObject.ProcessID = TRIM(ENTRY(2, CData, ' '))
TTObject.ThreadID = TRIM(ENTRY(3, CData, ' '))
TTObject.ObjectType = TRIM(SUBSTRING(CData, 89, (INDEX(CData, 'Handle:') - 89)))
TTObject.Created = TRUE
TTObject.ObjectHandle = INTEGER(ENTRY(1, SUBSTRING(CData, (INDEX(CData, 'Handle:') + 7), 20), ' '))
TTObject.ObjectDetails = CData.
I don't need to check the logic of the program - will the ASSIGN validate the uniqueness of the temp-table indexes or not. The explicit transaction block means the author of program thought about such things.
> Remove the DO TRANSACTION Block and the flow is 100% the same.
But TRANSACTION keyword was there only as a comment.
> You can resolve this for instance by adding this inside the DO TRANSCATION block
IMHO, the "comment" simply says where the error checks should be added if they are needed.
As with any "holy wars": people can read the different meaning looking at the same words.