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();
}
}

浙公网安备 33010602011771号