问题原因:

表缺少主键,或主键索引未创建。seata获取主键是通过索引来获取,查看源码可以发现,seata先将表所有的索引查询出来、再将主键索引查出来,如下图所示

查询所有索引的sql 对应代码中getIndexInfo方法

select null as table_cat,
       owner as table_schem,
       table_name,
       0 as NON_UNIQUE,
       null as index_qualifier,
       null as index_name, 0 as type,
       0 as ordinal_position, null as column_name,
       null as asc_or_desc,
       num_rows as cardinality,
       blocks as pages,
       null as filter_condition
from all_tables
where table_name = '表名'
  and owner = '用户名'
union
select null as table_cat,
       i.owner as table_schem,
       i.table_name,
       decode (i.uniqueness, 'UNIQUE', 0, 1),
       null as index_qualifier,
       i.index_name,
       1 as type,
       c.column_position as ordinal_position,
       c.column_name,
       null as asc_or_desc,
       i.distinct_keys as cardinality,
       i.leaf_blocks as pages,
       null as filter_condition
from all_indexes i, all_ind_columns c
where i.table_name = '表名'
  and i.owner = '用户名'
  and i.index_name = c.index_name
  and i.table_owner = c.table_owner
  and i.table_name = c.table_name
  and i.owner = c.index_owner
order by non_unique, type, index_name, ordinal_position;

查询主键索引 对应代码中getPrimaryKeys方法


SELECT NULL AS table_cat,
       c.owner AS table_schem,
       c.table_name,
       c.column_name,
       c.position AS key_seq,
       c.constraint_name AS pk_name
FROM all_cons_columns c, all_constraints k
WHERE k.constraint_type = 'P'
  AND k.table_name = '表名'
  AND k.owner like '用户名' escape '/'
  AND k.constraint_name = c.constraint_name 
  AND k.table_name = c.table_name 
  AND k.owner = c.owner 
ORDER BY column_name

查询出所有的索引后开始进行索引类型判断,如果和主键索引约束名constraint_name一致则设置索引类型为0。注意这里oracle会遇到坑,主键索引约束名constraint_name不能过长,超长了会使获取所有索引的查询返回结果中索引约束名constraint_name被截断(getIndexInfo方法查询结果被截断),导致设置索引类型失败。

解决方法

重新创建主键索引,并修改主键索引约束名constraint_name

By xbingo

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注