12

I found that the @Transactional is used to ensure transaction on repository method or on a service method.
@Lock is used on repository method to ensure locking of entity to provide isolation.

Some questions are raised in my mind:

  1. What are major difference/relations in these two annotations ?
  2. When to use @Transactional and when to use @Lock ?
  3. Is @Lock useful in distributed database system to provide data concurrency and consistency ?
kayesh parvez
  • 323
  • 1
  • 2
  • 9

1 Answers1

18

Transactional: Whenever you put @Transactional annotation, it enables transactional behavior which qualifies ACID properties

ACID: ACID (Atomicity, Consistency, Isolation, Durability) is a set of properties of database transactions intended to guarantee the validity even in the event of errors.

Atomic Guarantees that all operations in a transaction are treated as a single “unit”, which either succeeds completely or fails completely.

Consistent Ensures that a transaction can only bring the database from one valid state to another by preventing data corruption.

Isolation Determines how and when changes made by one transaction become visible to the other. Serializable and Snapshot Isolation are the top 2 isolation levels from a strictness standpoint.

Durable Ensures that the results of the transaction are permanently stored in the system. The modifications must persist even in case of power loss or system failures.


Lock: It should not be confused with transactional,@Lock enables locking behavior during a transaction

JPA has two main lock types defined.

  1. Pessimistic Locking
  2. Optimistic Locking

If you want to know more about Pessimistic and Obtimistic locking you can explore the internet, below is explanation from Baeldung,

Pessimistic Locking When we are using Pessimistic Locking in a transaction and access an entity, it will be locked immediately. The transaction releases the lock either by committing or rolling back the transaction.

Optimistic Locking In Optimistic Locking, the transaction doesn't lock the entity immediately. Instead, the transaction commonly saves the entity's state with a version number assigned to it.

When we try to update the entity's state in a different transaction, the transaction compares the saved version number with the existing version number during an update.

At this point, if the version number differs, it means that the entity can't be modified. If there is an active transaction then that transaction will be rolled back and the underlying JPA implementation will throw an OptimisticLockException.

Apart from the version number approach, we can use other approaches such as timestamps, hash value computation, or serialized checksum, depending on which approach is the most suitable for our current development context.

There are also other lock types available in spring

  • NONE: No lock.
  • OPTIMISTIC: Optimistic lock.
  • OPTIMISTIC_FORCE_INCREMENT: Optimistic lock, with version update.
  • PESSIMISTIC_FORCE_INCREMENT: Pessimistic write lock, with version update
  • PESSIMISTIC_READ: Pessimistic read lock.
  • PESSIMISTIC_WRITE: Pessimistic write lock.
  • READ: Synonymous with OPTIMISTIC.
  • WRITE: Synonymous with OPTIMISTIC_FORCE_INCREMENT.

Now answer to your questions

  1. What are the major differences/relations in these two annotations?

You will understand after reading above

  1. When to use @Transactional and when to use @Lock?

If you want transactional behavior then add @transactional and if your usecase requires locking and as per use case use appropriate locking

  1. Is @Lock useful in the distributed database system to provide data concurrency and consistency?

The two main tools we use to cope with concurrency are database transactions and distributed locks. These two are not interchangeable. You can't use a transaction when you need a lock. You can't use a lock when you need a transaction. source

Shailesh Chandra
  • 2,164
  • 2
  • 17
  • 25
  • can you be a bit more specific... I mean a what are the usual cases when a transaction can fail ? does transaction internally use any locking system ? – kayesh parvez Nov 10 '19 at 06:52
  • 1
    yes transactional locking happens to protect the resource and ensure ACID, Isolation plays a role here too, and last committed transaction wins, by default connection's isolation level is READ COMMITTED, which protects against dirty read – Shailesh Chandra Nov 10 '19 at 07:05
  • you can read more about locking during transaction at https://www.tutorialspoint.com/dbms/dbms_concurrency_control.htm – Shailesh Chandra Nov 10 '19 at 07:08
  • You guys can check this post and help me out? I'm trying to implement according to this post but without success: https://stackoverflow.com/questions/68351144/javax-persistence-transactionrequiredexception-no-transaction-is-in-progress-on – Daniel Henao Jul 13 '21 at 16:28
  • This will add more context : https://stackoverflow.com/questions/42530115/spring-data-pessimistic-write-returns-old-db-value gist : `@Lock` only works for that repository call and not the whole `@Transactional` method call – Harshil Apr 26 '22 at 03:34