02. Are You Using @Transactional's readOnly Option Correctly?

Introduction
Today, I want to talk about the readOnly option of @Transactional, which is often called a magic annotation in Spring.
Wait, @Transactional doesn't have a readOnly option?

Huh? @Transactional doesn't have a readOnly option. What's going on? Are we going to talk about something that doesn't exist?
Before we discuss readOnly, let's first clarify that there are two types of @Transactional.

Two annotations from different packages
Both ultimately aim to do the same thing. (In fact, Spring AOP supports both the javax package's transaction and Spring package's transaction.) The annotation provided through the Spring package offers more options.
Since this article focuses on explaining the role of readOnly, let's look up the details on Google (I don't want to go too far off-topic here...).
How Does @Transactional's readOnly Work?

Let's explore how @Transactional's readOnly works
First, let's take a closer look at the readOnly option.
-
It allows you to set the transaction as read-only.
-
It may or may not prevent writes from occurring within the transaction due to developer mistakes. (It depends on the JDBC Driver.)
First, let's check the API documentation for Spring transaction's readOnly option.
[
Transactional (Spring Framework 5.3.3 API) Defines zero (0) or more exception names (for exceptions which must be a subclass of Throwable), indicating which exception types must cause a transaction rollback. This can be a substring of a fully qualified class name, with no wildcard support at presen docs.spring.io
This just serves as a hint for the actual transaction subsystem; it will not necessarily cause failure of write access attempts. A transaction manager which cannot interpret the read-only hint will not throw an exception when asked for a read-only transaction but rather silently ignore the hint.
The official documentation states that this option provides a read-only hint.
This basically calls 'Connection.setReadOnly(true)'. This is why I said 'it may or may not' earlier.
Oracle Driver has supported the readOnly option for a long time, but MySQL Driver only started supporting it from version 5.6.5 onwards.
Additionally, H2 still doesn't support it, so you must be aware that it applies differently depending on the JDBC vendor.
(Related reference: wonwoo.ml/index.php/post/839)
How Does It Apply When Using Hibernate?
When the readOnly option is set, Hibernate sets the Session's Flush Mode to 'FlushMode.MANUAL' mode.
This means 'this transaction will not flush on commit.'

As a result, Hibernate won't call flush on the Entity, and changes are naturally ignored.
Also, since flush is not called and Dirty Checking is not performed, you can gain performance benefits.
(To explain how Dirty Checking works simply, it compares the Entity with its Snapshot. Skipping this process provides a performance advantage.)