Skip to content

Commit

Permalink
Use SELECT FOR UPDATE on PostgreSQL RMW ops (#3103)
Browse files Browse the repository at this point in the history
This is required to successfully perform read-modify-write operations
when PostgreSQL is in hot standby mode.

Fixes: #3039

Signed-off-by: Andrew Harding <aharding@vmware.com>
  • Loading branch information
azdagron authored May 24, 2022
1 parent c2057a4 commit 2d9eb69
Showing 1 changed file with 6 additions and 1 deletion.
7 changes: 6 additions & 1 deletion pkg/server/datastore/sqlstore/sqlstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,8 @@ func (ds *Plugin) Close() error {
// concurrently.
func (ds *Plugin) withReadModifyWriteTx(ctx context.Context, op func(tx *gorm.DB) error) error {
return ds.withTx(ctx, func(tx *gorm.DB) error {
if ds.db.databaseType == MySQL {
switch ds.db.databaseType {
case MySQL:
// MySQL REPEATABLE READ is weaker than that of PostgreSQL. Namely,
// PostgreSQL, beyond providing the minimum consistency guarantees
// mandated for REPEATABLE READ in the standard, automatically fails
Expand All @@ -611,6 +612,10 @@ func (ds *Plugin) withReadModifyWriteTx(ctx context.Context, op func(tx *gorm.DB
// isolation level, like SERIALIZABLE, which is not supported by
// some MySQL-compatible databases (i.e. Percona XtraDB cluster)
tx = tx.Set("gorm:query_option", "FOR UPDATE")
case PostgreSQL:
// `SELECT .. FOR UPDATE`is also required when PostgreSQL is in
// hot standby mode for this operation to work properly (see issue #3039).
tx = tx.Set("gorm:query_option", "FOR UPDATE")
}
return op(tx)
}, false)
Expand Down

0 comments on commit 2d9eb69

Please sign in to comment.