2016-11-14 14 views
0

私たちはフレームワークPostgresqlドライバをリファクタリングしてトランザクションを許可しています。プロセスでは、我々はいくつかの詳細 https://travis-ci.org/photodude/database/jobs/175596877php Postgresql pg_query():重複キー値が一意制約に違反しています

問題を有するドライバの関連部分がこのリンク

であると試験トラビスするために、次のエラーで

pg_query(): duplicate key value violates unique constraint DETAIL: Key (id)=(1) already exists

リンクを結果として生じるいくつかの問題を導入しています

https://github.com/joomla-framework/database/blob/master/src/Postgresql/PostgresqlDriver.php#L711-L819

問題と関連テスト(複数可)

あります

https://github.com/joomla-framework/database/blob/master/Tests/DriverPostgresqlTest.php#L1116-L1163

は、私はテーブルの列は、何らかの形で台無しにされていることを得るが、私は、テーブルの列が台無しにされるか、テストが正しく機能しても、どれだけのコードを修正する理由について途方に暮れてよ。

注:私はこの失敗をライン519で

答えて

0

はシーケンスを再起動し、[OK]を見えるテーブルを切り捨て準備し、準備ができていない文に関連していると考えているが、それはロールバックトランザクション内で実行されている場合、発生しません切り捨てるが、シーケンスの再起動will

Important: Because sequences are non-transactional, changes made by setval are not undone if the transaction rolls back. 

参照:

s1=> create table test1 (id serial primary key, a text not null); 
CREATE TABLE 
s1=> \d 
      List of relations 
Schema |  Name  | Type | Owner 
--------+--------------+----------+-------- 
public | test1  | table | albert 
public | test1_id_seq | sequence | albert 
(2 rows) 

s1=> insert into test1(a) values ('apple'); 
INSERT 0 1 
s1=> select * from test1; 
id | a 
----+------- 
    1 | apple 
(1 row) 

s1=> select * from test1_id_seq; 
sequence_name | last_value | start_value | increment_by |  max_value  | min_value | cache_value | log_cnt | is_cycled | is_called 
---------------+------------+-------------+--------------+---------------------+-----------+-------------+---------+-----------+----------- 
test1_id_seq |   1 |   1 |   1 | 9223372036854775807 |   1 |   1 |  32 | f   | t 
(1 row) 

s1=> insert into test1(a) values ('bannana'); 
INSERT 0 1 
s1=> select * from test1; 
id | a  
----+--------- 
    1 | apple 
    2 | bannana 
(2 rows) 

s1=> insert into test1(a) values ('bannana'); 
INSERT 0 1 
s1=> select * from test1; 
id | a  
----+--------- 
    1 | apple 
    2 | bannana 
    3 | bannana 
(3 rows) 

s1=> select * from test1_id_seq; 
sequence_name | last_value | start_value | increment_by |  max_value  | min_value | cache_value | log_cnt | is_cycled | is_called 
---------------+------------+-------------+--------------+---------------------+-----------+-------------+---------+-----------+----------- 
test1_id_seq |   3 |   1 |   1 | 9223372036854775807 |   1 |   1 |  30 | f   | t 
(1 row) 

s1=> begin; 
BEGIN 
s1=> alter sequence test1_id_seq RESTART WITH 1; 
ALTER SEQUENCE 
s1=> truncate table test1; 
TRUNCATE TABLE 
s1=> rollback; 
ROLLBACK 
s1=> select * from test1_id_seq; 
sequence_name | last_value | start_value | increment_by |  max_value  | min_value | cache_value | log_cnt | is_cycled | is_called 
---------------+------------+-------------+--------------+---------------------+-----------+-------------+---------+-----------+----------- 
test1_id_seq |   1 |   1 |   1 | 9223372036854775807 |   1 |   1 |  0 | f   | f 
(1 row) 

s1=> select * from test1; 
id | a  
----+--------- 
    1 | apple 
    2 | bannana 
    3 | bannana 
(3 rows) 

s1=> 
+0

「TRUNCATE ... RESTART IDENTITY」についても同じことが言えます。 –

+0

これは興味深いメモです。私はそれがここに特定の失敗にも適用されているか分からない。テストを分離すると、私はまだ失敗に終わります。これはプリペアドステートメントを使用することに関連していると思われます。これは、トランザクションを使用していない実行テストだけを実行するためです。 –

0

根本的な原因はまだわかりませんが、全体的な問題は単体テストに関連しています。 1つの失敗したテストだけがチェックされていても、テーブルシーケンスをグローバルに再起動しています。私たちはこの問題を回避する方法を見つけましたが、依然として根本的な原因を探しています。

また、すべてのドライバテストでtearDown()メソッドを改善する必要があることがわかりました。

関連する問題