错误:重复的键值违反了唯一约束“ xak1fact_dim_relationship”

问题描述

| 在删除某些行并根据来自Java的条件更新表时,出现以下错误。我的数据库是PostgreSQL 8.4。下面是错误: 错误:重复的键值违反唯一 约束\“ xak1fact_dim_relationship \” 导致此问题的代码如下:
/**
 * Commits job.  This does the following:
 * <OL>
 *  <LI> cancel previous datamart states </LI>
 *  <LI> drop diabled derived objects </LI>
 *  <LI> flip mirror relationships for objects with next states </LI>
 *  <LI> advance rolloff_state from start1 to complete1,from start2 to complete </LI>
 *  <LI> set 1/0 internal states to 0/-1 </LI>
 *  <LI> remove header objects with no letter rows </LI>
 *  <LI> mark mirror rel as OS if children are missing (e.g.,semantic w/o agg build) </LI>
 *  <LI> mark mirror rel as OS if int-map not in sync with dim base (e.g.,int-map SQL w/o semantic) </LI>
 * </OL>
 */
protected void CommitJobUnprotected()
    throws SQLException
{
    if (_repl.epiCenterCon== null)
        throw makeReplacementError(0);
    boolean oldAutoCommitStatus = _repl.epiCenterCon.getAutoCommit();

    try
    {

        _repl.epiCenterCon.setAutoCommit(false);

        Statement stmt = null;
        boolean committed = false;
        synchronized (SqlRepl.metaChangeLock)
        {
            try
            {
                stmt = _repl.epiCenterCon.createStatement();

                // update internal states for fact_dim_relationship
                metaExec(stmt,\"DELETE from fact_dim_relationship WHERE internal_state = -1 AND \"  +
                                \" EXISTS (SELECT 1 FROM fact_dim_relationship WHERE internal_state = 1)\",\" SELECT 1 from fact_dim_relationship WHERE internal_state = -1 AND \"  +
                                \" EXISTS (SELECT 1 FROM fact_dim_relationship WHERE internal_state = 1)\"); /*1*/
                metaExec( stmt,\"UPDATE fact_dim_relationship SET internal_state = internal_state - 1 \" +
                             \" WHERE EXISTS (SELECT 1 FROM fact_dim_relationship inner1 \" +
                             \"              WHERE inner1.internal_state = 1 \" +
                             \" AND inner1.fact_tbl_key = fact_dim_relationship.fact_tbl_key \" +
                             \" AND inner1.dim_base_key = fact_dim_relationship.dim_base_key ) \",\" SELECT 1 FROM fact_dim_relationship \" +
                             \" WHERE EXISTS (SELECT 1 FROM fact_dim_relationship inner1 \" +
                             \"              WHERE inner1.internal_state = 1 \" +
                             \" AND inner1.fact_tbl_key = fact_dim_relationship.fact_tbl_key \" +
                             \" AND inner1.dim_base_key = fact_dim_relationship.dim_base_key ) \"); /*5*/

                System.out.println(\"Update done on fact_dim_relationship\");
                _repl.doDrop(SqlReplLogger.DB_META,stmt,\"fact_agg\",\"SELECT fact_agg_key FROM fact_agg f WHERE \" +
                                                                      \" NOT EXISTS (SELECT 1 FROM fact_agg_letter l WHERE \" +
                                                                      \"                 f.fact_agg_key = l.fact_agg_key) \"); /*6*/

                _repl.doDrop(SqlReplLogger.DB_META,\"dim_base_agg\",\"SELECT dim_base_agg_key FROM dim_base_agg d WHERE \" +
                                                                          \" NOT EXISTS (SELECT 1 FROM dim_base_agg_letter l WHERE \" +
                                                                          \"                 d.dim_base_agg_key = l.dim_base_agg_key) \"); /*6*/

                CheckOutOfSync(stmt,null); /*7*/
                CheckOutOfSync(stmt,null); /*7*/

                metaExec( stmt,\" update mirror_relationship set relation_to_current = \'Out Of Sync\' \" +
                                \" where dim_col_intmap_key is not null \" +
                                \" and relation_to_current = \'One Back\' \" +
                                \" and not exists ( \" +
                                \"       select 1 \" +
                                \"       from mirror_relationship m2,dim_col_view c,dim_col_intmap i \" +
                                \"       where m2.dim_base_key = c.dim_base_key \" +
                                \"       and c.dim_col_key = i.dim_col_key  \" +
                                \"       and i.dim_col_intmap_key = mirror_relationship.dim_col_intmap_key \" +
                                \"       and m2.relation_to_current = \'One Back\') \",\" SELECT 1 FROM mirror_relationship \" +
                                \" where dim_col_intmap_key is not null \" +
                                \" and relation_to_current = \'One Back\' \" +
                                \" and not exists ( \" +
                                \"       select 1 \" +
                                \"       from mirror_relationship m2,dim_col_intmap i \" +
                                \"       where m2.dim_base_key = c.dim_base_key \" +
                                \"       and c.dim_col_key = i.dim_col_key  \" +
                                \"       and i.dim_col_intmap_key = mirror_relationship.dim_col_intmap_key \" +
                                \"       and m2.relation_to_current = \'One Back\') \"); /*8*/

                // clean out the tables used by mombuilder,aggbuilder,and semantics
                metaExec( stmt,\"delete from relation_intermediary\",\"select 1 from relation_intermediary\" );

                _repl.epiCenterCon.commit();
                committed = true;
            }
            finally
            {

                safeMetaRollbackIfNeeded( committed );
                _repl.safeClose( null,stmt );
            }
        } // end synchronized block
    }
    finally
    {
        _repl.epiCenterCon.setAutoCommit(oldAutoCommitStatus);
    }
}
第一条delete语句运行良好,但是在运行更新时会引发上述异常。我们支持SQLServer,Oracle和DB2,并且相同的代码可以在其他DB上正常运行。顺便说一下,我们在READ_COMMITTED事务级别上运行这些语句,并且如果在两次安全操作之间有任何失败的情况下,我们都将自动提交设置为关闭。如果我使用autocommit true运行上述代码,则代码工作正常!但是我们不应该这样做。我怀疑PostgreSQL的多版本并发控制功能,我是否错误地设置了隔离级别?请尽我所能。我可以提供您想要的任何信息。     

解决方法

        如果仅这组特定查询,请使用
SET CONSTRAINT
BEGIN;
SET CONSTRAINT = xak1fact_dim_relationship DEFERRED;
-- Do your SQL
COMMIT;
如果这是非常常见的情况,则可以更改数据库模式,也可以更改数据库模式以支持“ 3”。     

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...