Un-deadlock device database

This commit is contained in:
Neil Alexander 2020-08-20 17:55:56 +01:00
parent 150121d39a
commit 8c57745c82
No known key found for this signature in database
GPG key ID: A02A2019A2BB0944
2 changed files with 28 additions and 42 deletions

View file

@ -138,19 +138,13 @@ func (s *devicesStatements) insertDevice(
) (*api.Device, error) { ) (*api.Device, error) {
createdTimeMS := time.Now().UnixNano() / 1000000 createdTimeMS := time.Now().UnixNano() / 1000000
var sessionID int64 var sessionID int64
err := s.writer.Do(s.db, txn, func(txn *sql.Tx) error { countStmt := sqlutil.TxStmt(txn, s.selectDevicesCountStmt)
countStmt := sqlutil.TxStmt(txn, s.selectDevicesCountStmt) insertStmt := sqlutil.TxStmt(txn, s.insertDeviceStmt)
insertStmt := sqlutil.TxStmt(txn, s.insertDeviceStmt) if err := countStmt.QueryRowContext(ctx).Scan(&sessionID); err != nil {
if err := countStmt.QueryRowContext(ctx).Scan(&sessionID); err != nil { return nil, err
return err }
} sessionID++
sessionID++ if _, err := insertStmt.ExecContext(ctx, id, localpart, accessToken, createdTimeMS, displayName, sessionID); err != nil {
if _, err := insertStmt.ExecContext(ctx, id, localpart, accessToken, createdTimeMS, displayName, sessionID); err != nil {
return err
}
return nil
})
if err != nil {
return nil, err return nil, err
} }
return &api.Device{ return &api.Device{
@ -164,11 +158,9 @@ func (s *devicesStatements) insertDevice(
func (s *devicesStatements) deleteDevice( func (s *devicesStatements) deleteDevice(
ctx context.Context, txn *sql.Tx, id, localpart string, ctx context.Context, txn *sql.Tx, id, localpart string,
) error { ) error {
return s.writer.Do(s.db, txn, func(txn *sql.Tx) error { stmt := sqlutil.TxStmt(txn, s.deleteDeviceStmt)
stmt := sqlutil.TxStmt(txn, s.deleteDeviceStmt) _, err := stmt.ExecContext(ctx, id, localpart)
_, err := stmt.ExecContext(ctx, id, localpart) return err
return err
})
} }
func (s *devicesStatements) deleteDevices( func (s *devicesStatements) deleteDevices(
@ -179,36 +171,30 @@ func (s *devicesStatements) deleteDevices(
if err != nil { if err != nil {
return err return err
} }
return s.writer.Do(s.db, txn, func(txn *sql.Tx) error { stmt := sqlutil.TxStmt(txn, prep)
stmt := sqlutil.TxStmt(txn, prep) params := make([]interface{}, len(devices)+1)
params := make([]interface{}, len(devices)+1) params[0] = localpart
params[0] = localpart for i, v := range devices {
for i, v := range devices { params[i+1] = v
params[i+1] = v }
} _, err = stmt.ExecContext(ctx, params...)
_, err = stmt.ExecContext(ctx, params...) return err
return err
})
} }
func (s *devicesStatements) deleteDevicesByLocalpart( func (s *devicesStatements) deleteDevicesByLocalpart(
ctx context.Context, txn *sql.Tx, localpart string, ctx context.Context, txn *sql.Tx, localpart string,
) error { ) error {
return s.writer.Do(s.db, txn, func(txn *sql.Tx) error { stmt := sqlutil.TxStmt(txn, s.deleteDevicesByLocalpartStmt)
stmt := sqlutil.TxStmt(txn, s.deleteDevicesByLocalpartStmt) _, err := stmt.ExecContext(ctx, localpart)
_, err := stmt.ExecContext(ctx, localpart) return err
return err
})
} }
func (s *devicesStatements) updateDeviceName( func (s *devicesStatements) updateDeviceName(
ctx context.Context, txn *sql.Tx, localpart, deviceID string, displayName *string, ctx context.Context, txn *sql.Tx, localpart, deviceID string, displayName *string,
) error { ) error {
return s.writer.Do(s.db, txn, func(txn *sql.Tx) error { stmt := sqlutil.TxStmt(txn, s.updateDeviceNameStmt)
stmt := sqlutil.TxStmt(txn, s.updateDeviceNameStmt) _, err := stmt.ExecContext(ctx, displayName, localpart, deviceID)
_, err := stmt.ExecContext(ctx, displayName, localpart, deviceID) return err
return err
})
} }
func (s *devicesStatements) selectDeviceByToken( func (s *devicesStatements) selectDeviceByToken(

View file

@ -140,7 +140,7 @@ func generateDeviceID() (string, error) {
func (d *Database) UpdateDevice( func (d *Database) UpdateDevice(
ctx context.Context, localpart, deviceID string, displayName *string, ctx context.Context, localpart, deviceID string, displayName *string,
) error { ) error {
return sqlutil.WithTransaction(d.db, func(txn *sql.Tx) error { return d.writer.Do(d.db, nil, func(txn *sql.Tx) error {
return d.devices.updateDeviceName(ctx, txn, localpart, deviceID, displayName) return d.devices.updateDeviceName(ctx, txn, localpart, deviceID, displayName)
}) })
} }
@ -152,7 +152,7 @@ func (d *Database) UpdateDevice(
func (d *Database) RemoveDevice( func (d *Database) RemoveDevice(
ctx context.Context, deviceID, localpart string, ctx context.Context, deviceID, localpart string,
) error { ) error {
return sqlutil.WithTransaction(d.db, func(txn *sql.Tx) error { return d.writer.Do(d.db, nil, func(txn *sql.Tx) error {
if err := d.devices.deleteDevice(ctx, txn, deviceID, localpart); err != sql.ErrNoRows { if err := d.devices.deleteDevice(ctx, txn, deviceID, localpart); err != sql.ErrNoRows {
return err return err
} }
@ -167,7 +167,7 @@ func (d *Database) RemoveDevice(
func (d *Database) RemoveDevices( func (d *Database) RemoveDevices(
ctx context.Context, localpart string, devices []string, ctx context.Context, localpart string, devices []string,
) error { ) error {
return sqlutil.WithTransaction(d.db, func(txn *sql.Tx) error { return d.writer.Do(d.db, nil, func(txn *sql.Tx) error {
if err := d.devices.deleteDevices(ctx, txn, localpart, devices); err != sql.ErrNoRows { if err := d.devices.deleteDevices(ctx, txn, localpart, devices); err != sql.ErrNoRows {
return err return err
} }
@ -181,7 +181,7 @@ func (d *Database) RemoveDevices(
func (d *Database) RemoveAllDevices( func (d *Database) RemoveAllDevices(
ctx context.Context, localpart string, ctx context.Context, localpart string,
) error { ) error {
return sqlutil.WithTransaction(d.db, func(txn *sql.Tx) error { return d.writer.Do(d.db, nil, func(txn *sql.Tx) error {
if err := d.devices.deleteDevicesByLocalpart(ctx, txn, localpart); err != sql.ErrNoRows { if err := d.devices.deleteDevicesByLocalpart(ctx, txn, localpart); err != sql.ErrNoRows {
return err return err
} }