230227 TIL

William Parker·2023년 2월 27일

What is the lock?

Isolation level

Fisrt, befor understand the Lock, we shouldl know the what is the Isolation level.

Transaction isolation level means how much transactions are isolated each other, while we process various transactions at the same time. It can decide the standard which Applicable transaction is able to read the changed data from another tractions.

Four kind of the Isolation level

READ UNCOMMITTED

  • It can read the data which uncommitted data.
  • It could be occur the Dirty Read, Dirt Write.

READ COMMITTED

  • It can read only committed data.
  • It is based on ORACAL DBMS standard and most chosen.
  • It is possible to occur the Lost Update, Write Skew, Read Skew.

REPETABLE READ

  • In MySQL, a transaction ID is assigned to each transaction, and only changes made by a transaction number smaller than the transaction ID are read.
  • Make a backup in the Undo space and change the actual record value.
    Data backed up in Undo is periodically deleted.
    Phantom Read may occur.
  • A record is visible and invisible due to a change made by another transaction.
  • Undo is used to guarantee the point in time, but newly inserted records do not have undo.
  • InnoDB uses next key lock (record lock + gap lock) to solve the Phantom Read problem!

SERIALIZABLE

  • Execute all transactions in order.

The higher the transaction isolation level, the more resources are used and the performance deteriorates. In general, use either READ COMMITTED or REPEATABLE READ.

What is the Perssimistic Lock?

  • Assume transaction conflicts and lock.
  • Use the lock function of the DBMS. (ex. SELECT FOR UPDATE)
  • When data is modified, transaction conflicts can be checked immediately.

What is the Optimistic Lock?

  • Assume that transactions do not conflict.
  • It is a methodology that does not preempt by locking resources, but handles concurrency problems when committing.
  • JPA uses its own version control function. (You can also use hashcode or timestamp.)
  • You cannot check for conflicts until you commit the transaction.

Pessimistic locking can be done using the @Lock annotation in SpringDataJPA.

public interface UserRepository extends JpaRepository<User, Long> {
    @Lock(LockModeType.PESSIMISTIC_WRITE)
    @Query("select b from User b where b.id = :id")
    User findByIdForUpdate(Long id);
}

Additionally, if you are using Row JPA, you can specify lock directly through EntityManager.

entityManager.lock(user, LockModeType.OPTIMISTIC);

The types of LockModType that implement pessimistic locking in JPA are as follows.

  • PESSIMISTIC_READ
    Read-only from other transactions
  • PESSIMISTIC_WRITE
    Neither read nor write from other transactions
  • PESSIMISTIC_FORCE_INCREMENT
    Cannot read or write from other transactions + additionally performs versioning.

Pessimistic locking can degrade performance because it locks the retrieved record itself.

If performance issues are found, optimistic locking should be considered.

To use optimistic locking in SpringDataJPA, add @Version to entities.

@Entity
public class Board {

    @Id
    @GeneratedValue
    private Long id;

    @Version
    private Long version;
    
}

Now whenever an entity is modified, since JPA itself supports versioning, an ObjectOptimisticLockingFailureException exception occurs if the search and modification times are different.

The types of LockModType that implement optimistic locking in JPA are as follows.

OPTIMISTIC

  • Version checking is performed at the beginning of a transaction, and version checking is also performed at the end of a transaction.
  • If the versions are different, the transaction is rolled back.

OPTIMISTIC_FORCE_INCREMENT

  • Using optimistic locking, we additionally force the version to increment.
  • The version changes when another entity with a relationship is modified. (ex. If a comment is edited, the post version is also changed.)
    READ
  • Same as OPTIMISTIC.
    WRITE
  • Same as OPTIMSTIC_FORCE_INCREMENT.
    NONE
  • If an entity has a field with @Version applied, optimistic locking is applied.

If you use JpaRepository, you can specify LockModeType of @Lock annotation.

@Lock(LockModeType.OPTIMISTIC)
Optional<User> findByIdForUpdate(Long id);

The @Lock of JPA Repository Method of @Transactional isolation level has the following difference.

  • Isolation level defines the criteria by which the transaction can see data changed by other transactions.
  • Lock performs the function of preventing other transactions from accessing the data.

Organize
The @Lock of JPA Repository Method of @Transactional isolation level has the following difference.

  • Isolation level defines the criteria by which the transaction can see data changed by other transactions.
  • Lock performs the function of preventing other transactions from accessing the data.

Optimistic locking generally outperforms pessimistic locking, which locks records from the moment a processing request is received until processing is complete.

Depending on the nature of the data, there are cases where pessimistic locks are good, and this is the case.

There is one product in stock. 1 million users concurrently request orders. In the case of a pessimistic lock, all but one user waits to determine whether a transaction conflicts in advance. In other words, you don't have to know in advance that there is no stock, and you don't have to do complicated processing.

In the case of an optimistic lock, the user who sent the simultaneous request processes them sequentially, and only when the user commits, it is recognized that there is no inventory. In addition, since rollback is required as much as processing has been performed, resource consumption is greatly increased.

profile
Developer who does not give up and keeps on going.

0개의 댓글