yuqi1129 commented on code in PR #12781:
URL: https://github.com/apache/gravitino/pull/12781#discussion_r3914884830


##########
core/src/main/java/org/apache/gravitino/storage/relational/service/TagMetaService.java:
##########
@@ -625,6 +678,66 @@ private static void validateAllowedValue(TagPO tagPO, 
TagValue tagValue)
         Arrays.toString(allowedValues));
   }
 
+  void lockMetalakeForTagCreate(MetalakePO observedMetalakePO) {

Review Comment:
   Follow-up after the final concurrency polish: this is now covered by a real 
two-connection interleaving test, 
`testTagCreateWaitsForConcurrentParentDelete`. It holds the parent delete 
uncommitted, verifies create is blocked on the shared parent lock, then commits 
the delete and asserts `NoSuchEntityException` plus no orphan tag root.



##########
core/src/main/java/org/apache/gravitino/storage/relational/service/TagMetaService.java:
##########
@@ -625,6 +678,66 @@ private static void validateAllowedValue(TagPO tagPO, 
TagValue tagValue)
         Arrays.toString(allowedValues));
   }
 
+  void lockMetalakeForTagCreate(MetalakePO observedMetalakePO) {
+    OccWriteSupport.lockParentForChildWrite(
+        observedMetalakePO.getMetalakeName(),
+        Entity.EntityType.METALAKE,
+        () ->
+            SessionUtils.getWithoutCommit(
+                MetalakeMetaMapper.class,
+                mapper ->
+                    
mapper.selectMetalakeMetaByIdForShare(observedMetalakePO.getMetalakeId())),
+        null,
+        current -> Objects.equals(current.getMetalakeName(), 
observedMetalakePO.getMetalakeName()));
+  }
+
+  private void deleteTagWithVersion(NameIdentifier identifier, TagPO 
observedTagPO) {
+    OccWriteSupport.deleteWithVersion(
+        () ->
+            SessionUtils.getWithoutCommit(
+                TagMetaMapper.class,
+                mapper ->
+                    mapper.softDeleteTagMetaByIdAndVersion(
+                        observedTagPO.getTagId(), 
observedTagPO.getCurrentVersion())),
+        () -> tagWriteFailure(identifier, observedTagPO));
+  }
+
+  private RuntimeException tagWriteFailure(NameIdentifier identifier, TagPO 
observedTagPO) {
+    return OccWriteSupport.writeFailure(
+        identifier,
+        Entity.EntityType.TAG,
+        () ->
+            SessionUtils.getWithoutCommit(
+                TagMetaMapper.class,
+                mapper -> 
mapper.selectTagByTagIdForUpdate(observedTagPO.getTagId())),
+        null,
+        current ->
+            Objects.equals(current.getTagName(), observedTagPO.getTagName())
+                && Objects.equals(current.getMetalakeId(), 
observedTagPO.getMetalakeId()));
+  }
+
+  private List<TagPO> lockTagsForAssignment(List<TagPO> observedTagPOs) {

Review Comment:
   Follow-up after the final concurrency polish: 
`testTagAssignmentWaitsForConcurrentRenameAndRollsBack` now exercises the 
previously missing two-connection case. It keeps the rename uncommitted, 
verifies assignment waits on the batched tag lock, then commits and asserts the 
assignment fails as not-found with no relation row left behind.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to