The Key statement just helps us to find what's in the index, not to manage what goes in there. If the same value is in more than one item, the value and the ID are indexed. That's just the way it works.
If you want to enforce a unique value, I don't have the documentation open but the options in the Key statement help to identify what's there, so execute through it once and if you get an ID for a key value, it's not unique, loop until the user provides something unique.
I have the feeling you've already been there, done that. What am I missing? Sorry.
T
UV has the NO.DUPS keyword iirc.
I have the feeling you've already been there, done that. What am I missing? Sorry.
Presumably, you can put a write trigger on the file, and check the index for the value. Of course, you'd need to code to catch the disallowed write.
I don't think triggers will help because (IIRC) these are secondary processes that are fire asynchronously - trigger failure doesn't affect the write process. I did a Lot of unusual intersystem work with triggers in D3v9 and at this point I simply can't remember the basic flow, sorry.
I see what you mean now - you want to try to guarantee unique values in a multi-user "simultaneous update" environment. Aside from your READU/xref solution you could use the LOCK statement around the Key/Write combination. That could be a real performance issue in a high-volume environment where this block is hit frequently but a great many of these scenarios where people picture heavy concurrency really aren't, so millisecond locks like this go un-noticed.
A final but reluctant (overkill) suggestion would be to use the XSUEX "user exit". This is a very cool, virtually unknown feature that allows multiple processes to share the same memory space. In short you can use it like a sort of private lock table, and with a couple statements achieve the same functionality as a Lock statement without hitting the system lock table. This feature wasn't well documented prior to v9.0 but it's more of a "first class citizen" now.
In short, you're looking for inter-process functionality and here are two ways of accomplishing that without resorting to a new xref file and related read/updates.
HTH
T
From: Kevin Powick
On Thursday, 11 April 2013 06:07:12 UTC-4, Brian Speirs wrote:
Presumably, you can put a write trigger on the file, and check the index for the value. Of course, you'd need to code to catch the disallowed write.
I think that's pretty much as close as you can get to ensuring unique index keys. IMO, it's a bit of a hack for functionality that should exist within D3 itself.
I know we're supposed to consider triggers as the MV world's answer to referential integrity (RI), and they can help a lot, but MV products need to come a long way to match the RI functionality of RDBMS products. Leaving RI at the application level, or within triggers, leaves a lot to be desired..
I believe that in D3, the only way to guarantee no duplicate index keys is to maintain your own secondary cross-reference file, where the item IDs of this xref file are the index keys in the primary file. This way, you could use READU else/then on the xref file to lock index keys (item IDs).
This is more of a technical exercise than real world problem one is likely to encounter. I'm not overly worried that my current project will result in a file being updated with duplicate index keys, but unless I create a secondary xref file, as described above, the possibility of a duplicate index key does exist.
--
Kevin Powick
--
You're right on the INPUTERR thing, my bad. My task was to get triggers to work between systems, with updates here triggering updates there, with no code changes to the original source. This ultimately resulted in read/write triggers for both D3 Linux and Windows - not currently supported functionality but achievable with some rigorous code.
About XSUEX (also internally the u5b exit), there are times when we want inter-process data to be available immediately and we usually resort to file IO and locks to achieve it. Think about how Common is only common to a given process, not all users. XSUEX changes that. In a non-business scenario think about how cross-user data is critical for playing multi-user games. We're not writing games with these systems anymore but there is frequently a need for one process to hand a task over to another, or for processes to exchange messages with real-time data without polling a common file or using the expensive lock tables. Consider a scenario where a report is processing a million items and you want to know where it is from another process. You don't need to write a counter on every N iterations (disk/resource issue) - save the counter with a string assignment with XSUEX in the report generator and retrieve it with another dashboard process. you can monitor a lot of system activity like this. I think of this as just another D3 hidden gem. I have not yet done any sort of performance analysis on this but would be interested if anyone else does. These days I still tend to use disk IO with control tables just to keep code more portable, and because disk access isn't as expensive as it used to be, but I'm still curious about file lock penalties vs XSUEX memory locking … and for all I know XSUEX does do file IO internally somewhere anyway.
T
From: Kevin Powick
UV has the NO.DUPS keyword iirc.