Spring中事务的理解

Spring中事务的理解

什么是事务?

数据库操作最基本单元,逻辑上一组操作,要么都成功,否则失败。典型场景:银行转账。

四大特性:原子、一致、隔离、持久性。ACID特性。

原子性:要么都成功,不可分割,一个失败都都失败。

一致性:操作前后总量不变。比如两人都有100块钱,一共200,一个人转给另一个人后总量还是200

隔离性:多事务操作相互不会产生影响。比如两人都去操作同一条记录,两人间互不应影响。

持久性:提交之后,表中数据真正发生变化。

 

事务操作(搭建操作环境,以转账为例)

示例图:

 

 

 

步骤:

1、创建数据库,添加记录

 

 

 2、创建service和dao,完成对象创建和注入关系

service:

 //转账
    public void account() {
        userDao.reduce();
        userDao.addmoney();
    }

  dao:

public interface UserDao {
    public void update();
    public void addmoney();
    public void reduce();
}

  

 @Override
    public void addmoney() {
        String sql="update count set money=money+? where username=?";
        jdbcTemplate.update(sql,100,"李四");

    }

    @Override
    public void reduce() {
        String sql="update count set money=money-? where username=?";
        jdbcTemplate.update(sql,100,"张三");

    }

 

3:问题:如果上述过程出现异常,会出现问题

如何用事务解决:

 

 

 

事务操作(Spring事务管理介绍)

1、一般添加到service层

2、在spring中进行事务管理操作

  1、声明式事务管理(常用)

  2、编程式事务管理

3、声明式事务管理

  1、基于注解

  2、基于配置文件

4、在Spring进行声明事务管理,底层使用AOP思想。

5、事务管理API

(1)、提供一个接口,代表事务管理器,这个接口提供不同框架的不同实现类

 

 

 事务操作(注解式)

1、在配置文件中配置事务管理器

<!--创建事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--注入数据源-->
        <property name="dataSource" ref="dataSource"></property>
    </bean>

2、开启事务注解

  1、配置文件中引入tx命名空间

  2、开启事务注解

 <!--开启事务注解-->
    <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>

  3、在service类或方法上加事务注解:@Transactional

 

事务操作(声明式事务管理参数配置)
1、

 

 

2、propagation:事务传播行为

  1、多事务方法直接进行调用,这个过程中事务是如何进行管理的

 

 

 

 

 

 

3、isolation:事务隔离级别

不考虑隔离性会出现三个问题

  1、脏读:一个未提交事务读取到了另一个未提交事务的数据

 

 

  2、不可重复读:一个未提交事务读取到了另一个提交事务的数据

 

   3、幻读:一个未提交事务读取到了另一个提交事务的添加数据

 

设置事务隔离级别:Mysql默认用的是可重复读

 

 

 

 

 

4、timeout:超时时间

 

 

5、readOnly:是否只读

 

 

6、rollbackFor:回滚

 

 

7、norollbackFor:不回滚

 

 

事务操作(完全注解,使用配置类)

1、创建配置类

@Configuration
@ComponentScan(basePackages = "org.zhaojianhui.Spring")
@EnableTransactionManagement//开启事务
public class txConfig {
    //创建数据库连接池
    @Bean
    public DruidDataSource getDruid(){
        DruidDataSource druidDataSource=new DruidDataSource();
        druidDataSource.setDriverClassName("");
        druidDataSource.setUrl("");
        druidDataSource.setUsername("");
        druidDataSource.setPassword("");
        return druidDataSource;
    }
}

  

 

 


 

整合日志框架

Spring5建议使用log4j2,整合如下:

1、引入依赖:

 

<dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-api</artifactId>
      <version>2.11.2</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-core</artifactId>
      <version>2.11.2</version>
    </dependency>
      <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-slf4j-impl -->
      <dependency>
          <groupId>org.apache.logging.log4j</groupId>
          <artifactId>log4j-slf4j-impl</artifactId>
          <version>2.11.2</version>
          <scope>test</scope>
      </dependency>
      <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
      <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-api</artifactId>
          <version>1.7.30</version>
      </dependency>

  

 2、根目录下创建log4j2.xml的配置文件

<?xml version="1.0" encoding="UTF-8"?>
<configuration status="INFO">
    <appenders>
        <console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </console>
    </appenders>
    <loggers>
        <root level="info">
            <appenderRef ref="Console"/>
        </root>
    </loggers>
</configuration>

  


 @Nullable注解

1、可以使用在方法、属性、参数上面,表示方法返回可以为空、属性值可以为空、参数值可以为空。

2、

 

 

 

 


 

Spring5整合Junit4

1、引入依赖

<dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-test</artifactId>
          <version>5.2.0.RELEASE</version>
      </dependency>

  

2、创建测试类,使用注解方式完成 

@RunWith(SpringJUnit4ClassRunner.class)//单元测试框架
@ContextConfiguration("classpath:bean2.xml")//加载配置文件
public class Test4 {
    @Autowired
    private UserService userService;

    @Test
    public void test1() {
        userService.account();

    }
}

 

 

Spring5整合Junit5

@ExtendWith(SpringExtension.class)
@ContextConfiguration("classpath:bean2.xml")//加载配置文件
//@SpringJUnitConfig(locations = "classpath:bean2.xml") 上面的一种简化
public class Test4 {
@Autowired
private UserService userService;

@Test
public void test1() {
userService.account();

}
}

 

posted @ 2020-08-11 00:12  zhaojianhui  阅读(531)  评论(0编辑  收藏  举报