Rebus.PostgreSql
Rebus.PostgreSql copied to clipboard
Rebus.Injection.ResolutionException when multiple clients initialize transport concurrently
Firstly, I really like Rebus, and especially the PostgreSQL transport, because it allows me to simplify my service infrastructure. I am using it for some years now and had a lot of positive experiences with it.
But now, if I have multiple processes (e. g. 4) initializing the transport concurrently, I sometimes get the following exception. The transport table was already created earlier when I start the processes. This is a bit weird, because normally a create table should fail with relation ... already exists if the table already exists. But the concurrent DDL requests seem to collide somehow in PostgreSQL.
---> Rebus.Injection.ResolutionException: Could not resolve Rebus.Transport.ITransport with decorator depth 0 - registrations: Rebus.Injection.Injectionist+Handler
---> Rebus.Exceptions.RebusApplicationException: Error attempting to initialize SQL transport schema with messages table "public"."transport"
---> Rebus.Exceptions.RebusApplicationException: Error executing SQL command
CREATE TABLE "public"."transport"
(
id serial NOT NULL,
recipient text NOT NULL,
priority int NOT NULL,
expiration timestamp with time zone NOT NULL,
visible timestamp with time zone NOT NULL,
headers bytea NOT NULL,
body bytea NOT NULL,
PRIMARY KEY (recipient, priority, id)
);
---> Npgsql.PostgresException (0x80004005): 23505: duplicate key value violates unique constraint "pg_class_relname_nsp_index"
I would like to have an optional parameter automaticallyCreateTables in UsePostgreSql(this StandardConfigurer<ITransport> configurer, ...), to be able to avoid this conflict.
And maybe it would be helpful, if the CREATE TABLE and CREATE INDEX statements in the CreateSchemaAsync() methods would use IF NOT EXISTS. (Supported for CREATE TABLE since PostgreSQL 9.1, and for CREATE INDEX since 9.5`)
If a merge request is appreciated, let me know.
Found this post related to the issue: https://stackoverflow.com/questions/74261789/postgres-create-table-if-not-exists-%E2%87%92-23505
So the IF NOT EXISTS will probably not help on its own, but the following might.
select pg_advisory_xact_lock(12345);
-- any bigint value, but has to be the same for all parallel sessions
create table if not exists ...;
Rebus.PostgreSql 9.1.1 has retries around all of its schema initialization routines, which should fix this particular issue.
It's on NuGet.org now 🙂
Thank you! The change in 9.1.1 resolved my issue.