[JAVA] How to make @Transactional work that does not work if you use it incorrectly

The Spring annotation " @ Transactional "is convenient because it automatically executes a transaction just by attaching it to a method and rolls back when a RuntimeException occurs by default. However, there are cases where the transaction cannot be performed just by adding `` `@ Transactional, and it does not cause a build error, so when I actually moved it, the transaction was not performed. So, I have summarized how to use `` `@ Transactional``` to work.

Conditions for `` `@ Transactional``` to work

After moving it around and checking it, it seems that the following conditions must be met.

--It must be a public method of the class you are DI --Called directly by another class or framework that is DI

Public method of DI class

There is also a method of using Bean definition file as a method of DI class, but here we will describe the implementation using Spring annotation.

ServiceClass.java


@Service
public class ServiceClass {

    @Transactional
	public void updateDB() {
    	//DB update process
	}
}

In the above, `@ Service``` is attached to the class, but other annotations that do DI such as @ Controller``` and `` @ Repository``` will also work.

Call directly from another class that is DI

The class that calls the above ServiceClass is as follows.

ControllerClass.java


@RequestMapping("/sample/*")
@Controller
public class ControllerClass {

	@Autowired
	ServiceClass serviceClass;

    @RequestMapping(value = { "index" })
    public String index(){
    	serviceClass.updateDB();

        return "sample/index";
    }
}

This is also a class that is DI using `` `@ Controller. @autowired```The transaction works by automatically creating an instance of serviceclass using and calling the updatedb method.

Call directly from the framework

It also works when a method with @ Transactional is called from the Spring framework. In the following cases, the transaction operates when the request corresponding to the setting of @ RequestMapping comes and the method is called.

ControllerClass.java


@RequestMapping("/sample/*")
@Controller
public class ControllerClass {

    @Autowired
    ServiceClass serviceClass;

    @RequestMapping(value = { "index" })
    @Transactional
    public String index(){
        serviceClass.updateDB();

        return "sample/index";
    }
}

ServiceClass.java


@Service
public class ServiceClass {

    public void updateDB() {
        //DB update process
    }
}

Also, the transaction works in the same way when the method is called by specifying the time by `` `@ Scheduled```.

ControllerClass.java


@Controller
public class ControllerClass {

    @Autowired
    ServiceClass serviceClass;

    @Scheduled(cron = "0 0 10 * * *")
    @Transactional
    public String index(){
        serviceClass.updateDB();

        return "sample/index";
    }
}

Implementation example

Considering a practical implementation, I want to roll back even if an exception other than RuntimeException occurs.

@Transactional(rollbackFor = Exception.class)Set Exception and classes that inherit Exception to be rolled back when thrown.


 Try-catch with the calling method and divide the process according to success or failure.


#### **`ControllerClass.java`**
```java

@RequestMapping("/sample/*")
@Controller
public class ControllerClass {

    @Autowired
    ServiceClass serviceClass;

    @RequestMapping(value = { "exec" })
    public String exec(Model model){

        try {
            //Calling a method that makes a transaction
            serviceClass.transaction();

            //What to do if successful
            model.addAttribute("message", "The process was successful.");
        } catch (Exception e) {
            //Processing when processing fails
            if (e.getMessage() != null) {
                 model.addAttribute("message", e.getMessage());
            } else {
                 model.addAttribute("message", "An error has occurred.");
            }
            return "sample/index";
        }
        return "sample/complete";
    }
}

ServiceClass.java


@Service
public class ServiceClass {

    @Transactional(rollbackFor = Exception.class)
    public void transaction() throws Exception {
        //A series of processes that you want to transaction
        //If you want to roll back, throw Exception as below
        throw new Exception("Processing failed.");
    }
}

Recommended Posts

How to make @Transactional work that does not work if you use it incorrectly
MockMVC returns 200 even if I make a request to a path that does not exist
How to replace characters that you do not understand [Principle]
If you want to make a Java application a Docker image, it is convenient to use jib.
How to fix the problem that Aptana Studio does not start
How to interact with a server that does not crash the app
[Swift] If you want to use a URL that includes Japanese, use addingPercentEncoding.
[Error] How to resolve the event that the screen does not transition after editing
[Spring Boot] If you use Spring Boot, it was convenient to use a lot of util.
When @Transactional of Spring Boot does not work
If you use SQLite with VSCode, use the extension (how to see the binary file of sqlite3)
How to place a button that does not move by scrolling on TableView etc.
What to do if the JSONHint annotation does not work with lombok and JSONIC
How to use Maven that I can't hear anymore
If hash [: a] [: b] [: c] = 0 in Ruby, I want you to extend it recursively even if the key does not exist.
[Ruby] How to use rbenv (version `x.x.x'is not installed)
How to make JavaScript work on a specific page
If you want to use Mockito with Kotlin, use mockito-kotlin
How to make a jar with old Hadoop (hadoop-core-0.20.2-cdh3u6) in Gradle: (What to do if you get Could not expand ZIP ..)
What to do if you installed Ruby with rbenv but the version does not change
Memo that transitions to the login screen if you are not logged in with devise
How to use Map
How to use rbenv
How to use letter_opener_web
How to use with_option
How to use fields_for
How to use java.util.logging
How to use map
How to use collection_select
How to use Twitter4J
How to use active_hash! !!
How to use MapStruct
How to use hidden_field_tag
How to use TreeSet
[How to use label]
How to make shaded-jar
How to use identity
How to use hashes
How to use JUnit 5
How to use Dozer.mapper
How to use Gradle
How to use org.immutables
How to use java.util.stream.Collector
How to use VisualVM
Sidekiq-limit_fetch does not work
How to use Map
[Rails] Solving the problem that session timeout does not work
Convenient use of Map that you do not know unexpectedly
How to get the log when install4j does not start
What to do if you can't use the rails command
How to solve the problem that you can not pull image from docker hub with Minikube