I personally really like ATOMIC or USE LOCKING approach.
I also would like to show you second common scenario when ConcurrentModificationException is a pain and maybe pessimistic locking or atomic operation whould solve common performance issues.
Typical use case in applications is to create couple of new vertices and link them with each other (it's easy&quick part without concurrent modification) and link them with EXISTING vertices via edges. Existing vertices usually are shared among many updates (out_ in_).
Example:
NEW_ORDER'S ITEMS->NEW_ORDER -> CUSTOMER (high concurrent modification exposure)
-> ORDER_TYPE (very high concurrent modification exposure)
I can store data using two approaches:
#1.
Roundtrip 1: CREATE VERTEX NEW_ORDERITEM1.....
Roundtrip 2: CREATE VERTEX NEW_ORDERITEM2.....
Roundtrip 3: CREATE VERTEX NEW_ORDER.....
Roundtrip 4: CREATE EDGE HAS_ITEMS...
Roundtrip 5: CREATE EDGE HAS_ITEMS...
Roundtrip 6: CREATE EDGE HAS_ORDERS...
Roundtrip 7: CREATE EDGE HAS_TYPE
cons:
- roundtrips,chatty
- it's not transactional
- orphaned vertices in case of errors
#2 TX
Roundtrip 1: SELECT FROM ORDER_TYPE_RID
Roundtrip 2: SELECT FROM CUSTOMER_RID
Roundtrip 3: COMMIT
INSERT:NEW_ITEM,NEW_ITEM,NEW_ORDER
UPDATE: CUSTOMER, ORDER_TYPE
pros:
- fully transactional
- no orphaned vertices in case of errors
- in theory should be faster, less roundtrips
- less chatty
cons:
- higher exposure to concurrent modifications exception--> TX always has to send FULL newest document (CUSTOMER,ORDER_TYPE)
- cost of retrying is expensive especially if additional loading of fresh data is needed
- poor performance if there is many edges to CUSTOMER,ORDER_TYPE ( big serialized,deserialized objects via network)--> even higher chance for concurrent exception
PROPOSED SOLUTION:
If we could only send sql commands (like CREATE EDGE FROM #TEMP_RID TO CUSTOMER_RID) in TX_COMMIT, the OConncurentModificationException wouldn't be a huge problem and performance would be in theory optimal.
Second way, maybe more elegant and consistent is possibility to add UPDATE_TYPE for updates to TX_COMMIT (SET or MERGE) and execute updates as locked atomic record operation. If we do so, mentioned case can be done in ONE roundtrip even without loadings CUSTOMER,ORDER_TYPE preserving all advantages.
Best regards,
Pawel