Skip to content

Conversation

@singhpk234
Copy link
Contributor

About the changes

While reading code, i realized this particular check was not happening in the transaction i.e let say we observe a constrain violation because within a transaction we added some entries, we would not be able to find which entity caused the SQL constraint violation in the first place, we might get incorrect entity in the exception, though the exception remains the same.

The proposed fix just uses the same conenction which is being used in the transaction and uses that to do the lookup to make sure the entity is found correctly.

Checklist

  • 🛡️ Don't disclose security issues! (contact [email protected])
  • 🔗 Clearly explained why the changes are needed, or linked related issues: Fixes #
  • 🧪 Added/updated tests with good coverage, or manually tested (and explained how)
  • 💡 Added comments for complex logic
  • 🧾 Updated CHANGELOG.md (if needed)
  • 📚 Updated documentation in site/content/in-dev/unreleased (if needed)

@sfc-gh-prsingh sfc-gh-prsingh force-pushed the feature/jdbc-fix-transaction branch from 0516439 to 6b013ce Compare December 26, 2025 04:17
@sfc-gh-prsingh sfc-gh-prsingh force-pushed the feature/jdbc-fix-transaction branch from fd91797 to da34869 Compare December 30, 2025 02:10
@sfc-gh-prsingh sfc-gh-prsingh force-pushed the feature/jdbc-fix-transaction branch from da34869 to 192d787 Compare December 30, 2025 02:12
dimas-b
dimas-b previously approved these changes Dec 30, 2025
Copy link
Contributor

@dimas-b dimas-b left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍 Thanks, @singhpk234 !

Yet... CI failed 🤔

* @param <T> : Business entity class
* @throws SQLException : Exception during query execution
*/
private <T> List<T> executeSelectWithConnection(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this method is called from only one place... why not inline?

@github-project-automation github-project-automation bot moved this from PRs In Progress to Ready to merge in Basic Kanban Board Dec 30, 2025
Comment on lines -192 to -206
PolarisBaseEntity existingEntity =
lookupEntityByName(
callCtx,
entity.getCatalogId(),
entity.getParentId(),
entity.getTypeCode(),
entity.getName());
// This happens in two scenarios:
// 1. PRIMARY KEY violated
// 2. UNIQUE CONSTRAINT on (realm_id, catalog_id, parent_id, type_code, name) violated
// With SERIALIZABLE isolation, the conflicting entity may _not_ be visible and
// existingEntity can be null, which would cause an NPE in
// EntityAlreadyExistsException.message().
throw new EntityAlreadyExistsException(
existingEntity != null ? existingEntity : entity, e);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PG aborts the transaction when it encounters the error :

If a statement within a transaction raises an exception, the entire transaction is 
  aborted and all statements are rolled back. The transaction remains in an aborted state, 
  and no further SQL commands will be executed until a ROLLBACK command is issued.

hence a lookup after write failure is not possible, the tests failed because of this.
I changed to read before write attempt lets say we are working with SERIALIZABLE isolation would work now. I see and think more it was intentional :'( as the comment says, to do it this way worst case was we not able to get existing entity which would have been fine.

Now lookup before before write is gonna cause some perf issue (but only for certain cases) and wrapping writeEntity would elevate the scenario more, will need to run some benchmark before we check it in,

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thx for the research! That sounds like a good plan 👍

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alternatively, we could explicitly start a new Tx for lookupEntityByName only on failure... WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

precisely presently thats what we are doing in the current code, the connection is a separate connection than the one used in the transaction in cases of writeEntities or a completely different connection in writeEntity i am also debating the same is it worth it, i will run benchmark for this 50:50 R/W to see how much we deviate from prev numbers as recorded here : #1517 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants