Introduction to Spring transaction management -- xml declarative transaction management

Posted by me1000 on Fri, 28 Jan 2022 22:40:04 +0100

Spring transaction management simplifies the traditional transaction management process and reduces the workload of developers to a certain extent, because if spring transaction management is not used, programmers have to write programs to deal with it. They need to consider a series of problems such as how to connect with the database and driver adaptation, and it is not easy for the next programmer to take over;

If there is no transaction management, the code is as follows -

The general idea is that businesses have an activity where friends can give points to each other - a commonplace thing;

package charpter0618.one;
public interface GameRule {//Interface for giving points
public void zsJF(String giveuser,String receiveuser,Integer JF);
}
package charpter0618.one.next;
public class User {//Define user information so that the data is consistent with the table type on the database,
private Integer user_id;
private String user_name;
private Integer user_jifen;
public Integer getUser_id() {
	return user_id;
}
public void setUser_id(Integer user_id) {
	this.user_id = user_id;
}
public String getUser_name() {
	return user_name;
}
public void setUser_name(String user_name) {
	this.user_name = user_name;
}
public Integer getUser_jifen() {
	return user_jifen;
}
public void setUser_jifen(Integer user_jifen) {
	this.user_jifen = user_jifen;
}
@Override
public String toString() {
	return "User [user_id=" + user_id + ", user_name=" + user_name + ", user_jifen=" + user_jifen + "]";
}
}

package charpter0618.one.next;

import javax.annotation.Resource;

import org.springframework.jdbc.core.JdbcTemplate;

import charpter0618.one.GameRule;

public class PlayGame implements GameRule {
	@Resource(name="jdbcTemplate")
private JdbcTemplate jdbcTemplate;
	
	
public JdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}
	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}
@Resource(name="user")
	private User user;
	public void setUser(User user) {
		this.user = user;
	}
	public User getUser() {
		return user;
	}
	@Override   //Method of giving points
	public void zsJF(String giveuser,String receiveuser,Integer zsJF) {
		String sql="update userdata set user_jifen=user_jifen+? where user_name=?";
		this.jdbcTemplate.update(sql, zsJF, receiveuser);//After giving points, the other one should reduce the corresponding points synchronously
		//Assuming no transaction processing, demonstrate the results--
		String pra="update userdata set user_jifen=user_jifen-? where user_name=?";
		this.jdbcTemplate.update(pra, zsJF,giveuser );//After giving points, the other one should reduce the corresponding points synchronously 	}
}

The configuration file is as follows – no transaction is done –

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-4.3.xsd">
      <!-- Configure data source connection database -->
      <bean id ="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" autowire="byName">
     <!-- Configure the parameter driver for connecting to the database, url,User name, password -->
      <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
       <property name="url" value="jdbc:mysql://localhost:3306/company?serverTimezone=UTC"/>
       <property name="username" value="root"/>
       <property name="password" value="955945"/>
       </bean>
      <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" autowire="byName"/>
      <bean id="user" class="charpter0618.one.next.User"/>
      <bean id="gameRule" class="charpter0618.one.next.PlayGame" >       
      <property name="jdbcTemplate" ref="jdbcTemplate"/>
      </bean>
</beans>

In this case, if the execution is successful, it's OK. In case the code execution of the giver fails, the points of the point receiver will increase in the database, but the points of the giver will not decrease (the default initial points are 1000)

package charpter0618.one;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
	ApplicationContext app = new ClassPathXmlApplicationContext("NewFile.xml");
	GameRule game= (GameRule)app.getBean("gameRule");
	game.zsJF("jack", "mary", 50);
}
}

The results of successful implementation are as follows –

If an unexpected situation occurs during execution,
For simplicity, make the following changes - and do it again
Info: loaded JDBC Driver: com mysql. cj. jdbc. Driver Exception in thread "main" java. lang.ArithmeticException: / by zero at charpter0618. one. next. PlayGame. zsJF(PlayGame.java:33) at charpter0618. one. Test. main(Test.java:10)


The points are presented successfully, but the points of the giver are not reduced, which does not meet the requirements of the merchant. Therefore, the following modifications should be made –
① Transaction declaration based on xml configuration file - modify configuration file-

package charpter0618.one.next;

import javax.annotation.Resource;

import org.springframework.jdbc.core.JdbcTemplate;

import charpter0618.one.GameRule;

public class PlayGame implements GameRule {
	@Resource(name = "jdbcTemplate")
	private JdbcTemplate jdbcTemplate;

	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}

	@Resource(name = "user")
	private User user;

	public void setUser(User user) {
		this.user = user;
	}

	public User getUser() {
		return user;
	}

	@Override // Method of giving points
	public void zsJF(String giveuser, String receiveuser, Integer zsJF) {
		String sql = "update userdata set user_jifen=user_jifen+? where user_name=?";
		this.jdbcTemplate.update(sql, zsJF, receiveuser);// After giving points, the other one should reduce the corresponding points synchronously
		// Assuming no transaction processing, demonstrate the results--
		int x = 1 / 0;
		String pra = "update userdata set user_jifen=user_jifen-? where user_name=?";
		this.jdbcTemplate.update(pra, zsJF, giveuser);// After giving points, the other one should reduce the corresponding points synchronously
	}

}

After modification, if an error is encountered, the data will be rolled back

information: Loaded JDBC driver: com.mysql.cj.jdbc.Driver
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.springframework.cglib.core.ReflectUtils$1 (file:/C:/EC_Workspqce/charpter0618/src/main/webapp/WEB-INF/lib/spring-core-4.3.6.RELEASE.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)
WARNING: Please consider reporting this to the maintainers of org.springframework.cglib.core.ReflectUtils$1
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
Exception in thread "main" java.lang.ArithmeticException: / by zero
	at charpter0618.one.next.PlayGame.zsJF(PlayGame.java:33)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:564)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
	at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
	at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282)
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
	at com.sun.proxy.$Proxy6.zsJF(Unknown Source)
	at charpter0618.one.Test.main(Test.java:10)

Modify the data in the table as shown in the figure below, and execute again -

The data in the table are as follows –

You will find that the data has not been modified, which indicates that the transaction has been started successfully - that's all for today
Learn together, make progress together and witness growth!!!

Sometimes free is the most expensive. Chinese people are used to whoring for nothing......

Topics: Java Database Spring