[ https://issues.apache.org/jira/browse/HIVE-26882?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17823671#comment-17823671 ]
Rui Li commented on HIVE-26882: ------------------------------- I tested again with MariaDB and there're fewer commit conflicts in HMS log than in the test log. This is expected because iceberg checks for conflict itself before it calls {{alter_table}}. The number of conflicts triggered by HMS is the same as the number in HMS log. I also tested with Postgres and the result is correct. I read the [doc|https://www.postgresql.org/docs/14/transaction-iso.html#XACT-REPEATABLE-READ] and I think it works because: bq. a repeatable read transaction cannot modify or lock rows changed by other transactions after the repeatable read transaction began But I suspect this is stricter than the ANSI SQL standard. I checked SQL:2011, and it says the following about {{SERIALIZABLE}} level: bq. The execution of concurrent SQL-transactions at transaction isolation level SERIALIZABLE is guaranteed to be serializable. A serializable execution is defined to be an execution of the operations of concurrently executing SQL-transactions that produces the same effect as some serial execution of those same SQL-transactions. A serial execution is one in which each SQL-transaction executes to completion before the next SQL-transaction begins. Suppose we have these two concurrent transactions trying to update the property. IIUC the result can be either {{v1}} or {{v2}}, even for {{SERIALIZABLE}} level. {code:SQL} txn1> update tbl set val = 'v1' where key = 'k'; txn2> update tbl set val = 'v2' where key = 'k'; {code} Maybe another solution is to use direct SQL and checks for the number of affected rows to detect conflict. We did a PoC for this and it also provides the correct results. The pseudo code is like this: {code:Java} String key = ...; String expectedVal = ...; Table oldTable = ...; Table newTable = ...; Connection connection = getConnection(Connection.TRANSACTION_REPEATABLE_READ); try { Statement statement = connection.createStatement(); if (!expectedVal.equals(oldTable.getParameters().get(key))) { throw new MetaException("Table has been modified"); } int affectedRows = statement.executeUpdate("UPDATE TABLE_PARAMS SET PARAM_VALUE = 'new_val' WHERE TBL_ID = ... AND PARAM_KEY = 'key' AND PARAM_VALUE = 'expected_val'"); if (affectedRows != 1) { throw new MetaException("Table has been modified"); } connection.commit(); } catch (Throwable t) { connection.rollback(); throw t; } finally { connection.close(); } {code} A problem is each iceberg commit can modify multiple properties or even other table fields. So it can be difficult to generate all the SQLs manually. Not sure how (or whether possible) to do this with JDO. > Allow transactional check of Table parameter before altering the Table > ---------------------------------------------------------------------- > > Key: HIVE-26882 > URL: https://issues.apache.org/jira/browse/HIVE-26882 > Project: Hive > Issue Type: Improvement > Components: Standalone Metastore > Reporter: Peter Vary > Assignee: Peter Vary > Priority: Major > Labels: pull-request-available > Fix For: 2.3.10, 4.0.0-beta-1 > > Time Spent: 4h 40m > Remaining Estimate: 0h > > We should add the possibility to transactionally check if a Table parameter > is changed before altering the table in the HMS. > This would provide an alternative, less error-prone and faster way to commit > an Iceberg table, as the Iceberg table currently needs to: > - Create an exclusive lock > - Get the table metadata to check if the current snapshot is not changed > - Update the table metadata > - Release the lock > After the change these 4 HMS calls could be substituted with a single alter > table call. > Also we could avoid cases where the locks are left hanging by failed processes -- This message was sent by Atlassian Jira (v8.20.10#820010)