Обеспечение того, чтобы одновременные запросы для коротких URL-адресов не перезаписывались: лучшие методы и примеры кода

Службы сокращения URL-адресов стали неотъемлемой частью веб-приложений, позволяя пользователям обмениваться компактными ссылками. Однако когда несколько одновременных запросов пытаются создать короткий URL-адрес для одного и того же длинного URL-адреса, существует риск перезаписи данных и возникновения несогласованности. В этой статье мы рассмотрим несколько методов обеспечения целостности данных и предотвращения перезаписи одновременных запросов друг друга. Мы предоставим примеры кода, иллюстрирующие каждый подход.

Метод 1: транзакции базы данных
Одним из распространенных подходов к обработке одновременных запросов является использование транзакций базы данных. Транзакции позволяют сгруппировать несколько операций с базой данных в одну единицу работы. Обернув процесс создания URL-адреса в транзакцию, мы можем гарантировать, что только один запрос может одновременно фиксировать изменения в базе данных. Вот пример на Python с использованием библиотеки SQLAlchemy:

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
engine = create_engine('your_database_url')
Session = sessionmaker(bind=engine)
def create_short_url(long_url):
    session = Session()

    try:
        session.begin()
        # Check if the short URL already exists
        existing_url = session.query(ShortURL).filter_by(long_url=long_url).first()
        if existing_url:
            return existing_url.short_url

        # Create a new short URL
        short_url = generate_short_url()
        new_url = ShortURL(long_url=long_url, short_url=short_url)
        session.add(new_url)
        session.commit()

        return short_url
    except Exception as e:
        session.rollback()
        raise e
    finally:
        session.close()

Метод 2: механизмы блокировки
Другой подход заключается в использовании механизмов блокировки, чтобы гарантировать, что только один запрос может получить доступ к критическому разделу кода одновременно. Этого можно добиться с помощью мьютексов или семафоров. Вот пример на Java с использованием ключевого слова synchronized:

public class URLShortener {
    private static final Object lock = new Object();
    public synchronized String createShortURL(String longURL) {
        // Check if the short URL already exists
        String existingURL = checkExistingURL(longURL);
        if (existingURL != null) {
            return existingURL;
        }
// Create a new short URL
        String shortURL = generateShortURL();
        // Critical section
        synchronized (lock) {
            saveShortURL(longURL, shortURL);
        }
        return shortURL;
    }
    private String checkExistingURL(String longURL) {
        // Check if the short URL already exists in the database
        // Return the existing short URL if found, otherwise return null
    }
    private void saveShortURL(String longURL, String shortURL) {
        // Save the short URL to the database
    }
    private String generateShortURL() {
        // Generate a unique short URL
    }
}

Метод 3: Атомарные операции
Атомарные операции неделимы и не могут быть прерваны, что делает их полезными для параллельных сред. Используя атомарные операции, мы можем гарантировать, что процесс создания короткого URL-адреса выполняется атомарно, предотвращая перезапись. Вот пример на C# с использованием класса Interlocked:

public class URLShortener
{
    private static string shortURL;
    public string CreateShortURL(string longURL)
    {
        // Check if the short URL already exists
        string existingURL = CheckExistingURL(longURL);
        if (existingURL != null)
        {
            return existingURL;
        }
// Create a new short URL
        string newShortURL = GenerateShortURL();
        // Atomic operation
        Interlocked.CompareExchange(ref shortURL, newShortURL, null);
        return shortURL;
    }
    private string CheckExistingURL(string longURL)
    {
        // Check if the short URL already exists in the database
        // Return the existing short URL if found, otherwise return null
    }
    private string GenerateShortURL()
    {
        // Generate a unique short URL
    }
}

Предотвращение перезаписи в одновременных запросах на создание коротких URL имеет решающее значение для обеспечения целостности данных. В этой статье мы рассмотрели три метода достижения этой цели: использование транзакций базы данных, механизмов блокировки и атомарных операций. Каждый метод обеспечивает возможность гарантировать, что только один запрос может получить доступ к данным и изменить их одновременно. Внедряя эти методы, веб-разработчики могут с уверенностью предоставлять функции сокращения URL-адресов без ущерба для согласованности данных.