-
Notifications
You must be signed in to change notification settings - Fork 159
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
issue 2420 set Derby isolationLevel to avoid deadlock during ingestion #2415
Conversation
Signed-off-by: Robin Arnold <robin.arnold23@ibm.com>
'INSERT INTO ' || v_schema_name || '.' || p_resource_type || '_logical_resources (mt_id, logical_resource_id, logical_id, is_deleted, last_updated, version_id, current_resource_id) ' | ||
|| ' VALUES (?, ?, ?, ?, ?, ?, ?)'; | ||
EXECUTE stmt USING {{ADMIN_SCHEMA_NAME}}.sv_tenant_id, v_logical_resource_id, p_logical_id, p_is_deleted, p_last_updated, p_version, v_resource_id; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
interesting that we didn't set current_resource_id before... good find.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, we weren't setting it because we didn't establish the resource_id value until later in the procedure and it just felt wrong creating a relationship to something which didn't actually exist yet (because we haven't inserted the xx_resources row). But because the id value is obtained from a sequence, we can just grab the value early and use it right away when we do the very first insert into xx_logical_resources.
@@ -7,7 +7,7 @@ | |||
<!-- ============================================================== --> | |||
<!-- TENANT: default; DSID: default; TYPE: read-write --> | |||
<!-- ============================================================== --> | |||
<dataSource id="bootstrapDefaultDefault" jndiName="jdbc/bootstrap_default_default" type="javax.sql.XADataSource" statementCacheSize="200" syncQueryTimeoutWithTransactionTimeout="true" validationTimeout="30s"> | |||
<dataSource id="bootstrapDefaultDefault" jndiName="jdbc/bootstrap_default_default" type="javax.sql.XADataSource" statementCacheSize="200" syncQueryTimeoutWithTransactionTimeout="true" validationTimeout="30s" isolationLevel="TRANSACTION_READ_COMMITTED"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need to reflect the same with postgres/db2? based on the conversation, it sounds like no since the locks are the way you want.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For PostgreSQL default isolation level is Read Committed, which is what we want. For Db2, it's an open question because allegedly the default is Repeatable Read which is more restrictive than necessary, but it doesn't impact us in this case because of the better concurrency control implementation within Db2.
private void safeClose(ResultSet rs) { | ||
try { | ||
if (rs != null) { | ||
rs.close(); | ||
} | ||
} catch (SQLException x) { | ||
// NOP | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought ResultSets autoclose out of scope?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually, where is this used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it's not. I added this as part of debugging to see if actively closing the ResultSet would make a difference (thinking there might be a bug lurking underneath even though closing the statement should close any associated ResultSet). I'll remove.
if (logger.isLoggable(Level.FINEST)) { | ||
logger.finest("Creating " + tablePrefix + "_logical_resources row: " + v_resource_type + "/" + p_logical_id); | ||
} | ||
final String sql5 = "INSERT INTO " + tablePrefix + "_logical_resources (logical_resource_id, logical_id, is_deleted, last_updated, version_id, current_resource_id) VALUES (?, ?, ?, ?, ?, ?)"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks consistent/good
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM - changes make sense based on thread
fhir-persistence-jdbc/src/main/java/com/ibm/fhir/persistence/jdbc/derby/DerbyResourceDAO.java
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assuming we remove that unused safeClose method, this LGTM
Signed-off-by: Robin Arnold <robin.arnold23@ibm.com>
Also aligned the stored procedures for Db2 and PostgreSQL so they match the logic of the Derby DAO. This ended up eliminating an update statement which we were executing for new resources which could be avoided. This should help PostgreSQL in particular, because it avoids tombstones which would need to be vacuumed.
Signed-off-by: Robin Arnold robin.arnold23@ibm.com