提问人:Xingbo Ye 提问时间:10/23/2023 最后编辑:Christophe QuintardXingbo Ye 更新时间:10/23/2023 访问量:42
为什么 JPA JDBC 在一个事务中相互锁定?
Why JPA JDBC lock each other in one transaction?
问:
重命名表时@Transactional
注释导致锁定冲突的问题
场景:
我在单个事务中执行两个操作:
使用
jpa
将数据保存到临时表。使用
jdbcTemplate
重命名临时表。
我发现临时表被第一个操作阻止,这意味着重命名无法获得完成所需的锁。这让我感到困惑。
代码:
@HandlingTime @Transactional public void updateFromLocalFiles(@NotNull String materialFile, @NotNull String... statusFiles) { saveDataToTempTable(materialFile, statusFiles); checkDataIntegrity(); backupAndDeleteOriginTable(); replaceTemporaryToOriginTable(); dropExpiredTable(); }
saveDataToTempTable 调用此 jpa 函数
protected long saveAllToTempTable(List<AdwMaterialTemp> materialList) { List<AdwMaterialTemp> adwMaterialTemps = adwMaterialTempRepository.saveAllAndFlush(materialList); return adwMaterialTemps.size(); }
replaceTemporaryToOrigiinTable 调用此 jdbc 函数
public void changeTableName(String originTableName, String targetTableName) throws DataAccessException { String RENAME_TABLE_NAME = "ALTER TABLE %s RENAME TO %s;"; var sql = String.format(RENAME_TABLE_NAME, originTableName, targetTableName); jdbcTemplate.execute(sql); log.info(SQL_LOG, sql); }
我在数据库的processList中看到了这一点:
| 9289 | root | 172.20.0.1:63024 | sephora-product-management | Query | 1240 | Waiting for table metadata lock | ALTER TABLE adw_material_temp RENAME TO adw_material |
在 performance_schema.metadata_locks 中:
| OBJECT_TYPE | OBJECT_SCHEMA | OBJECT_NAME | COLUMN_NAME | OBJECT_INSTANCE_BEGIN | LOCK_TYPE | LOCK_DURATION | LOCK_STATUS | SOURCE | OWNER_THREAD_ID | OWNER_EVENT_ID |
| TABLE | sephora-product-management | adw_material_temp | NULL | 140332151913120 | SHARED_WRITE | TRANSACTION | GRANTED | sql_parse.cc:5737 | 9352 | 15429 |
| TABLE | sephora-product-management | adw_material_temp | NULL | 140331681928000 | EXCLUSIVE | TRANSACTION | PENDING | mdl.cc:3702 | 9353 | 19 |
我删除了跨肌注释。然后它起作用了。
答: 暂无答案
评论