Skip to content

Commit

Permalink
Use SELECT FOR UPDATE on PostgreSQL RMW ops (spiffe#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: spiffe#3039

Signed-off-by: Andrew Harding <aharding@vmware.com>
  • Loading branch information
azdagron authored and stevend-uber committed Oct 13, 2023
1 parent 83360cf commit c6a920d
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 c6a920d

Please sign in to comment.