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:
- What are major difference/relations in these two annotations ?
- When to use
@Transactional
and when to use@Lock
?- Is
@Lock
useful in distributed database system to provide data concurrency and consistency ?
The @Transactional annotation makes use of the attributes rollbackFor or rollbackForClassName to rollback the transactions, and the attributes noRollbackFor or noRollbackForClassName to avoid rollback on listed exceptions. The default rollback behavior in the declarative approach will rollback on runtime exceptions.
1 Answer. Show activity on this post. If you call method2() from method1() within the same class, the @Transactional annotation of the second method will not have any effect because it is not called through proxy, but directly.
The @Transactional annotation belongs to the Service layer because it is the Service layer's responsibility to define the transaction boundaries.
However, if we put the annotation on a private or protected method, Spring will ignore it without an error. Usually it's not recommended to set @Transactional on the interface; however, it is acceptable for cases like @Repository with Spring Data.
The Spring Transactional annotation is very handy when it comes to defining the transaction boundaries of business methods.
The annotation @EnableTransactionManagement tells Spring that classes with the @Transactional annotation should be wrapped with the Transactional Aspect. With this the @Transactional is now ready to be used. The Spring declarative transaction management mechanism is very powerful, but it can be misused or wrongly configured easily.
And then Spring is smart enough to transparently handle transactions for you: Any bean’s public method you annotate with the @Transactional annotation, will execute inside a database transaction (note: there are some pitfalls ). So, to get the @Transactional annotation working, all you need to do is this:
@Transactional (Declarative Transaction Management) vs Programmatic Transaction Management. Physical vs Logical transactions. Spring @Transactional and JPA / Hibernate integration. Spring @Transactional and Spring Boot or Spring MVC integration. Rollbacks, Proxies, Common Pitfalls and much more.
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.
- Pessimistic Locking
- 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
Now answer to your questions
You will understand after reading above
If you want transactional behavior then add @transactional and if your usecase requires locking and as per use case use appropriate locking
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With