Я получаю приведенную ниже ошибку при удалении некоторых строк и обновлении таблицы на основе условия из 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, stmt, "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, "fact_agg", null); /*7*/
CheckOutOfSync(stmt, "dim_base_agg", 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_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') "); /*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);
}
}
Первый оператор удаления прошел успешно, но при выполнении командыобновить это бросает вышеупомянутое исключение ....!Мы поддерживаем SQLServer, Oracle и DB2, и тот же код отлично работает с другими БД.Кстати, мы выполняем эти операторы на уровне транзакции READ_COMMITTED и отключаем автокоммит, если между ними что-то не получается, мы безопасно откатываемся.Если я запускаю приведенный выше код с autocommit true, код работает нормально!Но мы не должны этого делать.Я подозреваю, что в PostgreSQL имеется функция контроля параллельности нескольких версий, неправильно ли я устанавливаю уровень изоляции?Пожалуйста, помогите мне как можно раньше.Я могу предоставить любую информацию, которую вы хотите.