- - PR -
[PostgreSQL]トランザクション
1
| 投稿者 | 投稿内容 |
|---|---|
|
投稿日時: 2006-10-25 11:49
いつも参考にさせていただいております。
[悩み] トランザクションの処理が思ったように動きません。 [環境] OS:RedHatES4_0 DB:PostgreSQL8_1_4 言語:JAVA1.5 [やりたいこと] 例えば10件のレコードを登録する際に重複登録の際にはスキップして登録を実行するがそれ以外のSQLExceptionが発生した場合は、ロールバックする。 [現象] 例えば、10件のinsertを実行した場合、5件目で重複登録となりExceptionが発生する。 スキップして6件目の登録を実行するが、「すでにトランザクションは異常となっている」というようなメッセージが出て登録することが出来ない。 org.postgresql.util.PSQLException: ERROR: current transaction is aborted, commands ignored until end of transaction block at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:1525) at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1309) at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:188) at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:452) at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:354) at org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:308) [ソース] Connection conn = 〜; conn.setAutoCommit(false); Statement st = conn.createStatement(); try { st.execute("BEGIN TRANSACTION"); st.execute("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE"); for(int i=0;i<10;i++){ try{ st.executeUpdate("INSERT INTO 〜"); }catch(SQLException e){ if(重複登録 == true){ continue; }else{ throw e; break; } } } if(正常処理確認) { conn.commit(); } else { con.rollback(); } } catch(SQLException e) { conn.rollback(); } と、こんな感じ。 「conn.setAutoCommit」が鍵であるような気がする。 ■パターン1 conn.setAutoCommit(false); SQLExceptionが発生したらそれ以降の実行文は全て無効になってしまう。 ■パターン2 conn.setAutoCommit(true); トランザクション無視のロールバック不可能。 結局、 SQLExceptionの種類によってトランザクション中の処理をcommitしたりrollbackしたりすることは出来ないのでしょうか? 誰か、教えてください。 [ メッセージ編集済み 編集者: liwings 編集日時 2006-10-25 11:51 ] |
|
投稿日時: 2006-10-25 13:01
例外処理で、二重登録をスキップするのはあまりスマートなやり方ではないと思います。
登録前に存在チェックを行って、あればスキップ。無ければ登録とした方がよい気がします。 ただしこの場合において、複数のセッションから同時多発的に更新を行う場合は、テーブルをロックする必要は発生します。 またPostgreSQLって、更新エラーが発生すると、未コミットの更新内容はすべてご破算されてしまいます。 AutoCommitにしていれば別ですが。 |
|
投稿日時: 2006-10-25 14:20
セーブポイントを使うか
insert into select |
1
