Subject: RE: Creating a link from one form to another
While @DbLookup is certainly slower then accessing pre-existing data in the document, it’s basically foolproof – the data displayed are guaranteed to be up to date as of the moment the document is opened.
While there may be performance issues that can justify keeping copies of information, you pay for improved performance in decreased reliability, greatly increased complexity of your code, and information that less current. The programming task of keeping all the data consistent is non-trivial, especially if there are multiple replicas of the application.
Let’s take a simple example. FormA contains a list of “links” to FormB documents that have a matching key. This list is updated by an agent whenever a FormB document is added, updated or deleted (the update might involve changing the key value in FormB, so it should attach to a different FormA document).
That seems simple enough. But let’s suppose someone has a local replica of the application. They create a FormB document in their local replica. Later they open the FormA document with the same key. The link to their new document is missing. The agent runs on a server, and while they might have replicated their change to the server, they haven’t yet received the updated FormA document from the server.
Now let’s say someone in the server replica deletes a FormB document. Now there is an invalid link in a FormA document. How does the server agent know that a document has been deleted? There’s no “when documents deleted” trigger to run an agent. You would have to do something to make sure that every time a document was deleted, some code of yours would run to do an update. This involves either a really slow agent that checks all FormA documents to see whether the documents they refer to still exist, or writing DSAPI code – a possibility though not one that most Domino developers would savor – or some event being triggered by the user’s workstation immediately either just before or just after the document is deleted. Unfortunately, Domino doesn’t use a two-phase commit process. There’s every chance that an inconsistency will be caused by a failure in the code between the time one change is committed and the second change is attempted. The network connection could be lost just after saving or deleting the FormB document and before the FormA document can be updated. The user could press Ctrl+Break. The save to the FormA document could fail because of a save conflict. Worse, the save could succeed because you are overriding save conflicts, and someone else’s change could be overwritten.
Or, of course, if the application is on multiple servers (and/or local replicas) – inevitable for high-availability applications – do all servers update the documents, or only one of them? If all (which would include the case where related documents are updated immediately in form events), what’s to prevent replication conflicts when users on two different servers add FormB documents that contain the same key? If only one, there’s a double replication delay before links on other servers are up to date. What happens if that server is down? Does everyone have to wait for the server to come up before their links are up to date?
Plus, there are performance and other drawbacks to updating documents every time a related document changes. Changing documents unnecessarily causes additional churn in view indexes, increased replication times, loss of unread marks, and agents triggering unnecessarily on “modified” documents whose modifications are unimportant to the agent. The chance of save conflicts rises greatly – what happens if you’re editing a FormA document while someone else creates a FormB document with that same key?
If you do opt for having the related document updated automatically with code run on the user’s workstation, you either have to run it under the user’s ID (which means you have to allow all these users who can create/modify FormB documents access to edit all FormA documents) or you have to use RunOnServer, which is a bit more complicated and is also a bigger burden on the server, and which only works if there’s a server available (i.e. not in a disconnected local replica).
That’s why, when I recommend to someone how to create relationships between documents based on a key, storing link information in the documents is not the first thing that occurs to me to suggest. I’m not saying I wouldn’t do it that way ever, but not without a very good reason or special circumstances that make it easier to control for the above factors (e.g. the application is only accessed thru a web browser from one server, or performance is a serious problem and I’ve run out of other ways to address it).
Another way to accomplish this functionality that Claire might consider, is the use of an embedded single-category view (which might be in a section – that lets the user choose whether they want to wait for the update by opening the section). Or, she could use a live lookup that only is performed when the user presses a button – until then, they don’t know whether there are any related documents.