You may be tempted to write the life cycle operations as follows:
{zcode:slice}
interface PhoneEntry {
// ...
idempotent void destroy(); // Wrong!
};
interface PhoneEntryFactory {
idempotent PhoneEntry* create(string name, string phNum)
throws PhoneEntryExists;
};
{zcode} |
The idea is that create and destroy can be idempotent operations because it is safe to let the Ice run time retry the operation in the event of a temporary network failure. However, this assumption is not true. To see why, consider the following scenario:
destroy on a phone entry.ObjectNotExistException to the client, which the Ice run time passes to the application code.ObjectNotExistException and falsely concludes that it tried to destroy a non-existent object when, in fact, the object did exist and was destroyed as intended.A similar scenario can be constructed for create: in that case, the application will receive a PhoneEntryExists exception when, in fact, the entry did not exist and was created successfully.
These scenarios illustrate that create and destroy are never idempotent: sending one create or destroy invocation for a particular object is not the same as sending two invocations: the outcome depends on whether the first invocation succeeded or not, so create and destroy are not idempotent.