シーケンスはロールバックされません

知らなかった><

S2JDBC使っていて、ロールバックしてもシーケンスがインクリメントされたままになってるなぁと思って調べてた。
一応調べたことを書きます。

DB

PostgreSQL 8.1.11

company
CREATE SEQUENCE company_id_seq;
CREATE TABLE company (
  company_id INTEGER DEFAULT nextval('company_id_seq'),
  company_name VARCHAR(255) NOT NULL,
  PRIMARY KEY(company_id)
);

確認方法

テストクラスで、①.ロールバックさせる。②.トランザクション管理しないでinsertする。メソッドををそれぞれ作って実行した。

public void testTransactionFalseTx() throws Exception {
	// companyName が not null のため 制約違反
	Company entity = new Company();
	jdbcManager.insert(entity).execute();
}

public void testTransactionTrue() throws Exception {
	Company entity = new Company();
	entity.companyName = "A";
	jdbcManager.insert(entity).execute();
}

結果

company_id company_name
2 A

ロールバックしてるのにシーケンスがインクリメントされてる><

ログ確認

2009-01-31 19:54:23,933 [main] DEBUG org.seasar.extension.jta.TransactionImpl - トランザクションを開始しました。tx=[FormatId=4360, GlobalId=1233399263933/0, BranchId=]
2009-01-31 19:54:23,978 [main] DEBUG org.seasar.extension.jdbc.query.AutoInsertImpl - select nextval('COMPANY_ID_SEQ')
2009-01-31 19:54:24,046 [main] DEBUG org.seasar.extension.dbcp.impl.ConnectionPoolImpl - 物理的なコネクションを取得しました
2009-01-31 19:54:24,048 [main] DEBUG org.seasar.extension.dbcp.impl.ConnectionPoolImpl - 論理的なコネクションを取得しました。tx=[FormatId=4360, GlobalId=1233399263933/0, BranchId=]
2009-01-31 19:54:24,080 [main] DEBUG org.seasar.extension.jdbc.query.AutoInsertImpl - insert into COMPANY (COMPANY_ID, COMPANY_NAME) values (1, null)
2009-01-31 19:54:24,090 [main] DEBUG org.seasar.extension.jta.TransactionImpl - トランザクションロールバックしました。tx=[FormatId=4360, GlobalId=1233399263933/0, BranchId=]
2009-01-31 19:54:24,090 [main] DEBUG org.seasar.extension.dbcp.impl.ConnectionWrapperImpl - 論理的なコネクションを閉じました。tx=[FormatId=4360, GlobalId=1233399263933/0, BranchId=]
2009-01-31 19:54:24,091 [main] DEBUG org.seasar.extension.dbcp.impl.ConnectionWrapperImpl - 物理的なコネクションを閉じました

ちゃんとロールバックしてる><

もしかして…

同じシーケンスから数を取得するといった同時トランザクションの障害を 避けるために、nextval 演算はロールバックされることがありません。 つまり一度値が取りだされると、もしその nextval を行なったトランザクション が後でアボートしても、その値は使用済であると仮定されます。これは アボートされたトランザクションは未使用の"穴"を割り振られた値のシーケンス に残す可能性があります。setval 演算もロールバックされることはありません。

http://www.sraoss.co.jp/PostgreSQL/Manual/PostgreSQL-7.1-ja/sql-createsequence.html

シーケンスはロールバックされないのが正解でした。
危なく、Seasarメーリングリストに投稿するところだった。