Use @Transactional transaction management of SpringBoot

Outline

What is a transaction? Here is a simple example, if Bob is now going to transfer from their bank accounts to $ flowers 5W bank account, which involves two operations, the first one is put away in the small 5W clear the accounts, and the second is to put 5W block of imported flowers account, if the first step and the second step is operating normally out of the question, then we must ensure that first step out of operation can be revoked, otherwise the roof will Xiaoming met. . .
Then the transaction management is an effective means to solve this kind of problem, it guarantees a set of actions either completed (submitted Commit), or any link errors will withdraw all (rollback Rollback)!

Now we give a simple definition of transaction: A transaction is a set of operations to meet the ACID properties.
1. Atomicity (Atomicity)
transaction is considered indivisible minimum unit, all the operations of the transaction either all commit succeeds or all fail rolled back. Rollback can be used to achieve rollback logs, log roll back office operations performed by the modified reverse to perform these modifications upon rollback.
2. Consistency (Consistency)
database before and after the transaction execution are consistent state. In coherency state, all transactions of a reading result data is the same.
3. Isolation (Isolation)
a firm to make changes before final submission, other transactions are not visible.
4. Persistent (Durability)
modified once the transaction is committed, it will be done forever saved to the database. Even if the system crashes, the implementation of the outcome of the transaction can not be lost. Redo logs to ensure durability.

SpringBoot support transaction management:

1. programmatic transaction management
2. declarative transaction management

Simple comparison of the two ways of transaction management:
programmatic transaction management needs transaction management doping code in the business logic code, this non-invasive manner contrary to the Spring development advocated. The declarative transaction management built on the AOP on , its essence is a method to intercept before and after, and then create or join a transaction before the target method begins, commit or roll back the transaction in accordance with the implementation after executing the target method. As can be seen, declarative transaction management to make business code is not contaminated. Declarative transaction only downside is that it 'the most fine-grained can only be applied to the method level , you can not do as programmatic transaction that can be applied to the block level. But even if there is such a demand, there are many alternative methods, for example, can require transaction management code block is independent method and so on.

@Transactional annotation-based declarative transaction management easy to use, the contents of this article is to introduce.

Use of @Transactional

@Transactional can be applied to the interface, the interface methods, classes, and class method. When used as a class, the class of all public methods will have this type of transaction attributes. Take way of example, the method @Transactional marked with the label, when unchecked exceptions thrown in the implementation process, it will roll back. (What? You ask me what is unchecked exceptions, it is non abnormalities, including RuntimeException and its subclasses and Error, abnormalities and non abnormalities is well understood, such as null pointer exception, compile-time compiler is checking out only run the program up and running this will throw an exception, which is a non abnormalities, another example IOException, which is able to compile check it out, this is checked abnormalities).

Next, we simply have to test. (As used herein, MySQL database)

Before the test, but also add a simple, familiar MySQL friends may know, MySQL is the default auto-commit mode, each statement in a separate transaction, when this statement is finished, if executed successfully hidden type of transaction is committed, on failure of the implicit transaction is rolled back. For normal transaction management, it is in a group of related operations in a transaction, it is necessary to turn off auto-commit mode database.
I consider this issue when new to Spring transaction management, access to relevant information and later discovered the problem does not need to worry about us, developers speak broken heart of Spring has been automatically submitted attribute to false underlying connection .

I JUnit unit test, simply write a test method that each piece of data is added to the two different data tables, these two operations is regarded as one transaction, the following two tables structure and begin testing previously, two tables have no data.
Here Insert Picture Description
Here Insert Picture Description

Test 1: Do not use transaction management.

    //注入两个dao层爸爸
	@Autowired
	private SingleGraphDao singleGraphDao;
	@Autowired
	private GraphInfoDao graphInfoDao;
	
	@Test
	public void testA_InsertSingleGraph() {
		//创建两个实体类测试对象,并为他们简单的赋值
		GraphInfo test1 = new GraphInfo();
		test1.setGraphInfoId(1L);
		test1.setCity("夏威夷");
		
		SingleGraph test2 = new SingleGraph();
		test2.setGraphInfoId(1L);
		test2.setGraphAddr("xxx.jpg");
		
		//将两个插入操作视为一个事务
		//先执行第一个数据的插入
		graphInfoDao.insertGraphInfo(test1);
		//简单的抛出一个异常
		int i = 1;
		if (i == 1) {
			throw new RuntimeException();
		}
		//之后再执行第二个数据的插入
		singleGraphDao.insertSingleGraph(test2);
	}

At this time, the recording state of the data table
Here Insert Picture Description
Here Insert Picture Description
at this time arises dirty data.

Test two: open transaction support, @Transactional marked with labels, database records and deleted before

    //注入两个dao层大佬
	@Autowired
	private SingleGraphDao singleGraphDao;
	@Autowired
	private GraphInfoDao graphInfoDao;
	
	//相比于之前的代码,这里只是多了个@Transactional注解
	@Test
	@Transactional
	public void testA_InsertSingleGraph() {
		//创建两个实体类对象,为他们简单的赋值
		GraphInfo test1 = new GraphInfo();
		test1.setGraphInfoId(1L);
		test1.setCity("夏威夷");
		
		SingleGraph test2 = new SingleGraph();
		test2.setGraphInfoId(1L);
		test2.setGraphAddr("xxx.jpg");
		
		//将两个插入操作视为一个事务
		//先执行第一个数据的插入
		graphInfoDao.insertGraphInfo(test1);
		//简单的抛出一个异常
		int i = 1;
		if (i == 1) {
			throw new RuntimeException();
		}
		//之后再执行第二个数据的插入
		singleGraphDao.insertSingleGraph(test2);
	}

After performing the test, we look at the state of the data table
Here Insert Picture Description
Here Insert Picture Description
can be seen, although the code in the first insert operation without any problems, but because dished out RuntimeException entire transaction so the first insertion operation were withdrawn, this that is, a rollback operation (rollBack)

how about it? Spring's transaction management is not very simple ah ~

Written in the last: @Transactional effective only for public comment method, which is determined by the nature of the Spring AOP. If you're protected, private or default on the method of use @Transactional annotation visibility, it will be ignored, and no exception is thrown. By default, only the method from outside the caller will be captured AOP proxy, that is, within the class method calls other methods of this class does not cause internal affairs of behavior, even if the method is called annotation @Transactional modified.

Guess you like

Origin blog.csdn.net/u013568373/article/details/90543219