Блокировка БД с какой-либо изоляцией не работает должным образом в приложении Spring Boot JPA.JAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Блокировка БД с какой-либо изоляцией не работает должным образом в приложении Spring Boot JPA.

Сообщение Anonymous »

У меня есть простая таблица базы данных (PostgreSql) со следующими данными
Изображение

В приложении JPA весенней загрузки соответствующий класс Entity для этой таблицы определяется следующим образом:

Код: Выделить всё

import java.time.LocalDateTime;

import org.hibernate.annotations.UpdateTimestamp;

import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Data
@Entity
@Table(name = "counter", schema = "demo")
public class CounterRow {

@Id
private int row_id;
private int counter;
private String last_user;

@UpdateTimestamp
private LocalDateTime last_updated;
}
И репозиторий определяется следующим образом

Код: Выделить всё

import org.ravi.entity.CounterRow;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

public interface CounterRepository extends JpaRepository {

}
Теперь я инициализировал два потока для одновременного увеличения счетчика, и моя цель — добиться синхронизации между двумя потоками на уровне БД, а не на уровне приложения (т. е. не использовать синхронизированный или любой другой механизм распределенной блокировки)
Если каждый поток увеличивает счетчик в 5 раз (в цикле), я ожидаю, что окончательное значение счетчика увеличится на 10 по сравнению с нынешним значением. Однако я вижу, что оно увеличивается только в 5 раз, если предположить, что это может быть связано с неправильной синхронизацией БД.
Это класс, который запускает потоки обновления

Код: Выделить всё

package org.ravi;

import org.ravi.entity.CounterRow;
import org.ravi.repository.CounterRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
public class DbSyncTester {

@Autowired
private CounterRepository repository;

@PostConstruct
public void start() {
final Thread thread1 = getThread("Updater_Thread_1");
final Thread thread2 = getThread("Updater_Thread_2");
thread1.start();
thread2.start();
}

private Thread getThread(String threadName) {
return new Thread(getDbTask(), threadName);
}

private Runnable getDbTask() {
return () -> {
int loopCounter = 0;
while (loopCounter++ < 5) {
updateDb();
}
};
}

@Transactional(readOnly = false, isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
private void updateDb() {
log.info("Fetching the counter from the DB");
CounterRow counterRow = repository.findById(1).get();
log.info("Counter value: {}", counterRow.getCounter());
counterRow.setCounter(counterRow.getCounter() + 1);
counterRow.setLast_user(Thread.currentThread().getName());
repository.save(counterRow);
log.info("Updated the counter in the DB to {}", counterRow.getCounter());
}
}
Я добавил приведенную ниже строку кода в метод, надеясь добиться синхронизации на уровне БД, но безуспешно.

@Transactional(readOnly = false, изоляция = Isolation.READ_COMMITTED, распространение = Propagation.REQUIRED)

Я также пробовал использовать Isolation.SERIALIZABLE< /code>, по-прежнему не работает.
Пожалуйста, помогите мне разобраться в проблеме с блокировками на уровне БД с использованием приведенного выше кода.

Подробнее здесь: https://stackoverflow.com/questions/790 ... pa-applica
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «JAVA»