Giriş
Şu satırı dahil ederiz
import org.springframework.data.jpa.repository.Lock;
When using Spring Data, we can use the @Lock annotation in Spring repository methods to specify the desired lock mode.
LockModeType olarak
1. PESSIMISTIC_READ,
2. PESSIMISTIC_WRITE,
3. PESSIMISTIC_FORCE_INCREMENT
4. OPTIMISTIC_FORCE_INCREMENT
kullanılabilir
Aslında altta şöyle bir şeye denk
geliyor.
entityManager.lock(employee, LockModeType.PESSIMISTIC_WRITE);
Timeout
To lock entities pessimistically, set the lock mode to PESSIMISTIC_READ, PESSIMISTIC_WRITE, or PESSIMISTIC_FORCE_INCREMENT.
If a pessimistic lock cannot be obtained, but the locking failure doesn’t result in a transaction rollback, a LockTimeoutException is thrown.
Pessimistic Locking Timeouts
The length of time in milliseconds the persistence provider should wait to obtain a lock on the database tables may be specified using the javax.persistence.lock.timeout property. If the time it takes to obtain a lock exceeds the value of this property, a LockTimeoutException will be thrown, but the current transaction will not be marked for rollback. If this property is set to 0, the persistence provider should throw a LockTimeoutException if it cannot immediately obtain a lock.
If javax.persistence.lock.timeout is set in multiple places, the value will be determined in the following order:
1. The argument to one of the EntityManager or Query methods.
2. The setting in the @NamedQuery annotation.
3. The argument to the Persistence.createEntityManagerFactory method.
4. The value in the persistence.xml deployment descriptor.
LockModeType = PESSIMISTIC_READ
SELECT * FROM t WHERE i = 1 FOR SHARE;
LockModeType = PESSIMISTIC_WRITE
Örnek
Şöyle bir SQL
üretiyor.
'select id from table where id = ? for update wait 5'
Şöyle
yaparız.
interface WidgetRepository extends Repository<Widget, Long> {
@Lock(LockModeType.PESSIMISTIC_WRITE)
Widget findOne(Long id);
}
LockModeType = OPTIMISTIC_FORCE_INCREMENT Örnek
Elimizde şöyle bir kod
olsun@Entity
public class Product {
@Id
private Long id;
private String name;
private int quantity;
@Version
private Long version;
// Getters and setters
}
@Repository
public interface ProductRepository extends
JpaRepository<Product, Long> {
@Lock(LockModeType.OPTIMISTIC_FORCE_INCREMENT)
Optional<Product> findById(Long id);
}
Kaydederken saveAll() için şöyle
yaparız. Böylece bir sürü satır tek bir SQL cümlesi ile kaydedilir.
spring.jpa.properties.hibernate.jdbc.batch_versioned_data=true
Kullanmak için şöyle
yaparız createProduct() işleminde flush() çağrılıyor. Böylece aynı versiyon numarasına sahip iki tane istek gelse bile flush() sayesinde hata varsa hemen görebiliriz
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
@Transactional
public void updateProducts(List<Product> products) {
productRepository.saveAll(products);
}
@Transactional
public void createProduct(Product product) {
productRepository.save(product);
productRepository.flush(); // commit the transaction
}
}