Java 用于临时表的postgresql线程安全

Java 用于临时表的postgresql线程安全,java,postgresql,Java,Postgresql,这是我用于创建临时表的语法: create temp table tmpTable (id bigint not null, primary key (id)) on commit drop; 我知道这意味着在每个事务结束时,该表将被删除。 我的问题是,如果同一会话上的两个或多个线程创建值并将值插入到临时表中,它们将各自获得自己的实例,还是在会话中共享临时实例?如果它是共享的,有没有办法使它在每个线程上都是本地的 谢谢 Netta临时表对同一会话中的所有操作都可见。因此,在删除已存在的临时表(

这是我用于创建临时表的语法:

create temp table tmpTable (id bigint not null, primary key (id)) on commit drop;
我知道这意味着在每个事务结束时,该表将被删除。 我的问题是,如果同一会话上的两个或多个线程创建值并将值插入到临时表中,它们将各自获得自己的实例,还是在会话中共享临时实例?如果它是共享的,有没有办法使它在每个线程上都是本地的

谢谢
Netta

临时表对同一会话中的所有操作都可见。因此,在删除已存在的临时表(在您的案例中提交事务)之前,您不能在同一会话中创建同名的临时表

您可能需要使用:

CREATE TEMP TABLE tmptbl IF NOT EXISTS ...


唯一临时表 要使temp表成为每个“线程”(在同一会话中)的本地表,需要使用唯一的表名。一种方法是使用未绑定的
序列
和动态SQL-在过程语言(如plpgsql)或DO语句中(基本相同,没有存储函数)

运行一个:

CREATE SEQUENCE myseq;
使用:

要了解最新的表名,请执行以下操作:

SELECT 'tmp' || currval('myseq');
或者将其全部放入plpgsql函数并返回表或重用表名

不过,所有进一步的SQL命令都必须动态执行,因为普通SQL语句使用硬编码标识符进行操作。因此,最好将其全部放入plpgsql函数中


使用相同临时表的唯一ID 另一种可能的解决方案是对同一会话中的所有线程使用相同的临时表,并向表中添加一列
线程id
。如果大量使用该功能,请确保对该列进行索引。然后对每个线程(在同一会话中)使用唯一的
线程id

仅一次:

CREATE SEQUENCE myseq;
每个线程一次:

CREATE TEMP TABLE tmptbl(thread_id int, col1 int) IF NOT EXISTS;
my_id :=  nextval('myseq'); -- in plpgsql
-- else find another way to assign unique id per thread
SQL:


它们是共享一个DB连接,还是每个线程都有自己的连接?关键是每个线程需要不同的临时表。没有办法创建本地临时表吗?@netta:临时表是会话的本地表。如果您想使用相同的名称操作,请使用单独的会话。否则您必须使用我添加的动态SQL对于我的答案。或者每个线程使用一个唯一的ID-我在我的答案中添加了另一个想法。这在PostgreSQL中是非常优雅的。做得很好,先生。如果临时表标记为ON COMMIT DROP,PG将如何处理访问该表的多个线程?任何线程都可以提交,但该表在使用中不能被删除。@IamIC:只有一个transact-DROPion一次可以在同一个会话中运行。所以这种情况是不可能的。理论上这是可以改变的(AFAIC),但这就是它的实现方式。
CREATE TEMP TABLE tmptbl(thread_id int, col1 int) IF NOT EXISTS;
my_id :=  nextval('myseq'); -- in plpgsql
-- else find another way to assign unique id per thread
INSERT INTO tmptbl(thread_id, col1) VALUES
(my_id, 2), (my_id, 3), (my_id, 4);

SELECT * FROM tmptbl WHERE thread_id = my_id;