Adding concurrency control in our updateMovieHandler and documenting it.
All checks were successful
Deploy Greenlight API / deploy (push) Successful in 57s
All checks were successful
Deploy Greenlight API / deploy (push) Successful in 57s
This commit is contained in:
@@ -110,10 +110,11 @@ func (m MovieModel) Get(id int64) (*Movie, error) {
|
||||
// Update : Updating a specific record in the movies table
|
||||
func (m MovieModel) Update(movie *Movie) error {
|
||||
// Declare the SQL query for updating the record and returning the new version number.
|
||||
// Add the 'AND version = $6' clause to prevent data race
|
||||
query := `
|
||||
UPDATE movies
|
||||
SET title = $1, year = $2, runtime = $3, genres = $4, version = version +1
|
||||
WHERE id = $5
|
||||
WHERE id = $5 AND version = $6
|
||||
RETURNING version`
|
||||
|
||||
// Create an args slice containing the values for the placeholder parameters.
|
||||
@@ -123,10 +124,21 @@ func (m MovieModel) Update(movie *Movie) error {
|
||||
movie.Runtime,
|
||||
pq.Array(movie.Genres),
|
||||
movie.ID,
|
||||
movie.Version,
|
||||
}
|
||||
|
||||
// Use the QueryRow() method to execute the query, passing in the args slice as a variadic parameter and scanning the new version value into the movie struct.
|
||||
return m.DB.QueryRow(query, args...).Scan(&movie.Version)
|
||||
// Execute the SQL query. If no matching row could be found, we know the movie version has changed (or the record has been deleted) and we return our custom ErrEditConflict error.
|
||||
err := m.DB.QueryRow(query, args...).Scan(&movie.Version)
|
||||
if err != nil {
|
||||
switch {
|
||||
case errors.Is(err, sql.ErrNoRows):
|
||||
return ErrEditConflict
|
||||
default:
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete : Deleting a specific record from the movies table
|
||||
|
||||
Reference in New Issue
Block a user