Spring get to know a text database transaction operation!

Author | Arabic, Zebian | Guo Rui

Head Figure | CSDN download from Eastern IC

Exhibition | CSDN (ID: CSDNnews)

Today we understand together under Spring's transaction database operations. In operation database, we often use to the transaction, aims to provide a convenient Spring API developer specialized for processing transactions call, then this article will focus on speaking off his Spring-related functions for the transaction.

Core interface Spring affairs

Spring through a spring-tx-4.3.6-RELEASE JAR packages named to manage the affairs, org.Springframework.transaction package in the JAR package contains three interfaces file:

  • PlatformTramsactionManager primarily used to manage the transaction, including obtaining the status of a transaction, commit the transaction and roll back the transaction;

  • TramsactionDefinition The interface is defined subject matters, including the name of the acquisition transaction isolation level, propagation behavior of the transaction, timeout, whether the transaction is read-only;

  • TramsactionStatus The interface is a state of affairs, describes a certain point in time the transaction status information, including flush the transaction, whether or not there is a save point acquisition, whether it is a new transaction, whether or not rolled back, set the transaction is rolled back.

Examples to explain

Next we will explain the way how to use annotations by way of example to process transactions through the Spring, we increase the JAR package procedures affairs of the pom.xml in maven:

 <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>4.3.6.RELEASE</version>
    </dependency>

We first prepare a database:

CREATE TABLE IF NOT EXISTS `user`(
                `id` INT UNSIGNED AUTO_INCREMENT,
                `username` VARCHAR(100) NOT NULL,
                `password` VARCHAR(40) NOT NULL,
                `jifen` int(10) NOT NULL,
                PRIMARY KEY ( `id` ))ENGINE=InnoDB DEFAULT CHARSET=utf8;

Then writes some data to the database, including the user name, password, and the integral, as follows:

MariaDB [spring_db]> select * from user;
+----+----------+----------+-------+
| id | username | password | jifen |
+----+----------+----------+-------+
|  1 | zhangsan | 123      |  1000 |
|  2 | lisi     | 1234     |  1000 |
|  3 | wangwu   | 1234     |  1000 |
+----+----------+----------+-------+
3 rows in set (0.000 sec)

We need to do is to be transferred to John Doe Joe Smith points.

We need to create a User class, as follows:

package com.SpringDemo;

public class User {
    private Integer id;
    private String username;
    private String password;
    private Integer jifen;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void  setJifen(Integer jifen){
        this.jifen = jifen;
    }
    public Integer getjifen() {
        return jifen;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String toString() {
        return "User [id=" + id + ", username=" + username + ", password=" + password + "]";
    }
}

Then create an interface UserDao:

package com.SpringDemo;

import java.util.List;

public interface UserDao {
    public int addUser(User user);
    public int updateUser(User user);
    public int deleteUser(int id);
    //通过id查询用户
    public User findUserById(int id);
    //查询所有用户
    public List<User> findAllUser();
    public void transfer(String outUser,String inUser,Integer jifen);
}

In UserDao interface we define a transfer method, which includes the three parameters are outUser, inUser, jifen.

Then to define our implementation class UserDAOImpl:

package com.SpringDemo;

import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

public class UserDaoImpl implements UserDao {
    private JdbcTemplate jdbcTemplate;
    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }
    @Override
    public int addUser(User user) {
        String sql="insert into user(username,password) value(?,?)";
        Object[] obj=new Object[]{
                user.getUsername(),
                user.getPassword()
        };
        int num=this.jdbcTemplate.update(sql,obj);
        return num;
    }

    @Override
    public int updateUser(User user) {
        String sql="update user set username=?,password=? where id=?";
        Object[] params=new Object[]{
                user.getUsername(),
                user.getPassword(),
                user.getId()
        };
        int num=this.jdbcTemplate.update(sql,params);
        return num;
    }

    @Override
    public int deleteUser(int id) {
        String sql="delete from user where id=?";
        int num=this.jdbcTemplate.update(sql,id);
        return num;
    }

    @Override
    public User findUserById(int id) {
        String sql="select * from user where id=?";
        RowMapper<User> rowMapper=new BeanPropertyRowMapper<User>(User.class);
        return this.jdbcTemplate.queryForObject(sql,rowMapper,id);
    }

    @Override
    public List<User> findAllUser() {
        String sql="select * from user";
        RowMapper<User> rowMapper=new BeanPropertyRowMapper<User>(User.class);
        return this.jdbcTemplate.query(sql,rowMapper);
    }

    @Override

    public void transfer(String outUser, String inUser, Integer jifen) {
        // 赠送积分
        this.jdbcTemplate.update("update  user set jifen=jifen+? where username=?",jifen,inUser);
        // 模拟系统运行时的突发性问题
        int i =1/0;
        //赠送出积分
        this.jdbcTemplate.update("update user set jifen=jifen-? where username=?",jifen,outUser);

    }
}

Next we define a applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.3.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<!--1.配置数据源 -->
<bean id="dataSource"
      class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <!--数据库驱动 -->
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <!--连接数据库的ur1 -->
    <property name="url" value="jdbc:mysql://192.168.10.128:3306/spring_db" />
    <!--连接数据库的用户名 -->
    <property name="username" value="root" />
    <!--连接数据库的密码 -->
    <property name="password" value="123456" />
</bean>
<!--2.配置JDBC模板 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <!--默认必须使用数据源 -->
    <property name="dataSource" ref="dataSource" />
</bean>
<!--3.定义id为userDao的Bean -->
<bean id="userDao" class="com.SpringDemo.UserDaoImpl">
    <!--将 jdbcTemplate注入到 userDao实例中 -->
    <property name="jdbcTemplate" ref="jdbcTemplate" />
</bean>
<!--4.事务管理器,依赖于数据源 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>
<!--5.注册事务管理驱动 -->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
</beans>

Spring's transaction management methods are two kinds, one is the traditional programmed transaction management, that is to manage the start of a transaction through code execution and exception and rollback, one is declarative management, that is, by way of the configuration file, the principle of AOP is through technology, we recommend using the declarative transaction management in the actual development process, the efficiency will be greatly improved, since only need to configure.

In this interface, we rewrite our method of transfer, update the database will inUser points were increased, while the corresponding outUser points to be reduced, but here we want to simulate some sudden problems of system operation. Then we added a @Transactionl notes, and set up propagation, Isolation, readOnly three parameters.

 @Override
  @Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,
    readOnly = false)
    public void transfer(String outUser, String inUser, Integer jifen) {
        // 赠送积分
        this.jdbcTemplate.update("update  user set jifen=jifen+? where username=?",jifen,inUser);
        // 模拟系统运行时的突发性问题
        int i =1/0;
        //赠送出积分
        this.jdbcTemplate.update("update user set jifen=jifen-? where username=?",jifen,outUser);

    }

Parameter Meaning Notes @Transactional as follows:


@Transactional addition DEFAULT, there are other attributes, we can see the relative positioning in this class Isolation
@Transactional annotation can be added to the class level. When the @Transactional annotation on the class level, represent all public methods of the class configured with the same transaction attribute information.

public enum Isolation {
    DEFAULT(-1),
    READ_UNCOMMITTED(1),
    READ_COMMITTED(2),
    REPEATABLE_READ(4),
    SERIALIZABLE(8);

    private final int value;

    private Isolation(int value) {
        this.value = value;
    }

    public int value() {
        return this.value;
    }
}

Propagation properties as follows:

public enum Propagation {
    REQUIRED(0),//表示当前方法必须运行在一个事务环境中,如果存在就直接使用,否则开启一个新的事务执行该方法
    SUPPORTS(1),//如果当前方法处于事务环境中则使用,否则不使用事务
    MANDATORY(2),//表示该方法的线程必须在事务中否则抛出异常
    REQUIRES_NEW(3), //要求在新事务中执行,如果已经在事务中了则先暂停然后启动新事务执行,如果不在则启动一个新事务后执行
    NOT_SUPPORTED(4), //不支持当前事务,总是以非事务状态执行,如果调用该方法的线程处于事务中泽先暂停然后执行
    NEVER(5), //不支持当前执行的方法在事务中,如果在抛出异常
    NESTED(6); //即便当前执行的方法在事务中也会启动一个新事务,然后执行该方法

    private final int value;

    private Propagation(int value) {
        this.value = value;
    }

    public int value() {
        return this.value;
    }
}

In addition the @Transactional must ensure is used in a method public level of, @ Transactional only apply to public method to be effective, it is because when using Spring AOP proxy, Spring TransactionInterceptor before calling back and forth to intercept the target method execution, DynamicAdvisedInterceptor (CglibAopProxy inner classes) the intercept method JdkDynamicAopProxy or indirectly invoke method calls AbstractFallbackTransactionAttributeSource (Spring transaction attributes @Transactional annotation get through this class configuration attribute information) of computeTransactionAttribute method.

Next we create a test class to be tested:

package com.SpringDemo;


import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TransactionTest {
    public static void main(String[] args) {
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userDao = (UserDao) applicationContext.getBean("userDao");
        userDao.transfer("zhangsan","lisi",100);
        System.out.println("赠送积分成功");

    }

}

We perform the above procedures, it can be found in the error. Program News:

Exception in thread "main" java.lang.ArithmeticException: / by zero

as the picture shows:

At this point, we see the data in the database without any changes:

MariaDB [spring_db]> select * from user;
+----+----------+----------+-------+
| id | username | password | jifen |
+----+----------+----------+-------+
|  1 | zhangsan | 123      |  1000 |
|  2 | lisi     | 1234     |  1000 |
|  3 | wangwu   | 1234     |  1000 |
+----+----------+----------+-------+
3 rows in set (0.000 sec)

When we int i = 1/0; Zhushidiao will find the program execution performed again not being given, and the data changed:

MariaDB [spring_db]> select * from user;
+----+----------+----------+-------+
| id | username | password | jifen |
+----+----------+----------+-------+
|  1 | zhangsan | 123      |   900 |
|  2 | lisi     | 1234     |  1100 |
|  3 | wangwu   | 1234     |  1000 |
+----+----------+----------+-------+
3 rows in set (0.000 sec)

Well, that's about Spring's transaction management presentation.

【END】

More exciting recommended

gains GitHub 2000+ Star, Ali cloud platform open source machine learning how to beat the Alink 11 double data "game"? | AI technology ecological theory

2020 Nian, AI chip memory strong Which?

Please, do not ask me what is a B + tree

programmer Why should unequivocally oppose "best practices"?

half hour training one hundred million scale mapping knowledge, open source Amazon AI knowledge representation framework embedded map DGL-KE

"debut" 5-year adoption rate of 78%, what is the recipe for success Kubernetes?

alert! Emergence of new tricks: the false two-dimensional code generator has been successfully steal $ 460 million!

Today's welfare: Comments area selected message, get the value of 299 yuan, "2020 AI developers million Meeting" online live ticket . Come fingertips, write down what you want to say it.

Click to read the original, wonderful to continue!

Your point of each "look", I seriously as a favorite

Released 1929 original articles · won praise 40000 + · Views 18,040,000 +

Guess you like

Origin blog.csdn.net/csdnnews/article/details/105384204