タイトルの通りですが、PostgreSQL では、TRUNCATE TABLE も トランザクション内なので、ロールバックすると データは元に戻ります。
次のようになります。
postgres=# select * from test1; f1 | f2 ----+---- 1 | 1 2 | 2 (2 rows) postgres=# begin; BEGIN postgres=# truncate table test1; TRUNCATE TABLE postgres=# select * from test1; f1 | f2 ----+---- (0 rows) postgres=# rollback; ROLLBACK postgres=# select * from test1; f1 | f2 ----+---- 1 | 1 2 | 2 (2 rows)
面白いのは、CREATE TABLE などもトランザクション内です。
postgres=# begin; BEGIN postgres=# create table test2 (f1 varchar(1), f2 int); CREATE TABLE postgres=# select * from test2; f1 | f2 ----+---- (0 rows) postgres=# rollback; ROLLBACK postgres=# select * from test2; ERROR: relation "test2" does not exist
当然、このトランザクションがコミットするまでは、 別のトランザクションからは test2 テーブルは見えません。
別のトランザクションが絡んでくると少しややこしくなります。
トランザクション A がトランザクション中にテーブルを作成しているときに 他のトランザクション B が同じテーブル名でテーブルを作成しようとすると トランザクション B は A の結果待ちになります。
トランザクション A がロールバックして テーブルの作成がキャンセルされた場合 トランザクション B がテーブルを作成できるので、 トランザクション B はトランザクションを継続できます。
しかし、トランザクション A がコミットして テーブルを作成が確定してしまった場合は、 トランザクション B はテーブルの作成ができないのため B 側は、次のエラーが発生します。
ERROR: duplicate key value violates unique constraint "pg_type_typname_nsp_index"
DROP TABLE も同様のことが起こります。
あまりこういったケースはないと思いますが、 この辺りの動きは Oracle と異なるので注意が必要です。