首页 > 解决方案 > 如果同时运行,BIGSERIAL 事务是否安全?(PostgreSQL,libpqxx)

问题描述

假设我有以下表格。

CREATE TABLE IF NOT EXISTS Game
(
    GameNr         BIGSERIAL PRIMARY KEY,
    blabla         int --More values
);


CREATE TABLE IF NOT EXISTS player
(
    GameNr         BIGINT references Hand (HandNr),
    FOO            int --More values
);

并遵循 C++ 代码:一个事务类中的 2 个简单插入语句。


pqxx::connection database_connection("CONNECT TO DATABASE INFORMATION");

database_connection.prepare("Game_Insert", "INSERT INTO Game(blabla)\
        VALUES($1)\
RETURNING gamenr");


database_connection.prepare("player_Insert",INSERT INTO player(GameNr,FOO "\
 VALUES($1, $2)");

pqxx::work work(database_connection);

try
{
        pqxx::result result = work.exec_prepared("Game_Insert",2);

        int64_t game_nr;
        result.at(0).at(0).to(game_nr);

        for(const auto& player: players)
        {       
             result = work.exec_prepared("player_Insert",game_nr,2);
        }


        work.commit();

    }
    catch (const std::exception& e) {
        std::cout << e.what() << "\n";
        work.abort();
    }

现在这段代码同时运行了很多次。BIGSERIAL 序列会发生什么情况,数字或重复项之间是否存在任何间隙?

谷歌搜索给了我令人困惑的答案。

标签: c++postgresql

解决方案


您不必担心 bigserial 和 bigint 之间的区别。Bigserial 实际上并没有成为数据类型,将列定义为 bigint,创建序列,并将序列用作默认值是一种方便。数据类型变为 bigint 请参见下面的创建表和表说明。

postgres=# create table Games(GameNr bigserial, blabla integer);
    CREATE TABLE
    postgres=# \d+ games
                                                   Table "public.games"
     Column |  Type   |                       Modifiers                        | Storage | Stats target | Description
    --------+---------+--------------------------------------------------------+---------+--------------+-------------
     gamenr | bigint  | not null default nextval('games_gamenr_seq'::regclass) | plain   |              |
     blabla | integer |                                                        | plain   |              |


    postgres=#

并且在某些时候会有间隙,总是有序列,但没有重复。


推荐阅读