一、什么是事务
(本颜色字体为引导,帮助读者更易分辨重点和简单点)
(1)事务就是数据库操作最基本单元,逻辑上一组操作,要么都成功,如果有一个失败所有操作都失败。
(2)典型场景:银行转账
二、事务的四大特性(ACID)
概念性的东西稍微了解即可
(1)原子性
不可分割,要么成功,要失败都失败。
(2)一致性
转账之前,转账之后两个人总的钱是一样的
(3)隔离性
两个人操作同一条记录不会产生影响
(4)持久性
提交之后,表中数据发生变化
三、事务操作(搭建事务操作环境)
前期准备,需认真看。本部分通过模拟一个转账环境,帮助读者了解事务操作。
在一个转账环境之下,我们会有三层结构
(1)WEB层:用户可视化操作层
(2)Service层:书写业务逻辑
(3)Dao层:编写数据库的操作
下面是具体操作
1、创建bank数据库表,添加记录
2、创建service,搭建dao,完成对象和关系的注入
(1)配置依赖,service注入dao,在dao中注入JdbcTemplate,在JdbcTemplate注入DataSource
pom.xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
Dao类:
package thing;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
@Repository
public class UserDaoImpl implements UserDao{
@Autowired
private JdbcTemplate jdbcTemplate;
}
Service类
package thing;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
//注入Dao
@Autowired
private UserDao userDao;
}
注入JdbcTemplate:
<?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:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
">
<!--引入外部文件-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///bank"/>
<property name="username" value="root"/>
<property name="password" value="wuguixin"/>
</bean>
<!--注入jdbc模版-->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--扫描包-->
<context:component-scan base-package="thing"></context:component-scan>
</beans>
(2)在Dao中创建两个方法,一个多钱的方法,一个少钱的方法(先在Dao接口中设计相关方法,再在实现类中重写方法)
(3)在Service类中执行相关操作
(4)执行测试
(5)测试结果
四、事务操作(Spring事务管理)
概念性的东西稍微了解即可
1、事务一般添加到JavaEE的三层结构的Service层中
2、在Spring中进行事务管理操作
(1)有两种方式:编程式事务管理和声明式事务管理(一般都使用声明式)
3、声明式事务管理
(1)基于注解方式(更加简单方便)
(2)基于xml方式(基本不用)
本文不讲xml方式实现,因为开发效率较低
4、在Spring进行声明式事务管理,底层使用AOP原理
5、Spring事务管理API
(1)在.class文件中输入
import org.springframework.transaction.*;
(2)control+H对准PlatformTransactionManager查找继承结构
Spring做任务管理是通过接口做到的,针对不同的框架有不同的接口
笔者用的是durid数据库连接池,整合了jdbc框架,所以用的是DataSourceTransactionManager
如果整合的是Hibernate框架用的则是HibernateTransactionManager接口
五、事务操作(注解声明式事务管理)
事物操作的流程,认真看
1、在spring配置文件中配置事务管理器
<!-- 创建事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入数据源-->
<property name="dataSource" ref="dataSource"></property>
</bean>
2、在spring配置文件,开启事务注解
(1) 在spring配置文件中引入名称空间tx
<?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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
(2)开启事务注释
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
3、在service类上面(获得service类里面方法上面)添加事务注解
- @Transactional, 这个注解可以添加到类上面,也可以添加到方法上面
- 放到类上就等于所有方法添加注解
package thing;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional
public class UserService {
//注入Dao
@Autowired
private UserDao userDao;
public void operation(){
userDao.addMoney();
userDao.reduceMoney();
}
}
4、测试
(1)测试代码
@Test
public void test1(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("thing.xml");
UserService userService = applicationContext.getBean("userService",UserService.class);
userService.operation();
}
(3)测试分析
测试分析:当我们在这个类中注解@Transactional,如果发生了异常,事务就会回滚。所以operation执行步骤会是
addMoney() -> 10/0(发生Exception) -> 事务回滚 = operation()方法没执行
六、事务操作(声明式事务管理参数配置)
事物操作的参数,需要掌握
1、propagation:事务的传播行为
当一个事务方法被另一个事物方法调用的时候,那么这个事物如何进行
Required就是新插队旧事物
Required_NEW就是必须执行新事物,挂起旧事物
Support就是变成串行了,新事物的方法直接加入旧事物中,变成一个事物。
2、isolation:隔离等级
为了解决并发操作出现的问题,多事物操作之间不会产生影响。
如不采用隔离,可能出现:
脏读:读到未提交数据(因为事物有可能回滚)
不可重复读:第一次读和第二次读的数据不一样(因为另一个事物修改了数据)
虚读:当未提交数据也读到了另一事物修改的数据导致两次读数据不一样
设置隔离级别
注:MySQL默认设置的是RepeatableRead
3、timout:
超时时间
(1)事物在一定时间内一定要提交,不然就事物回滚
(2)默认是-1,代表不超时
(3)设置时间以秒单位计算
3、readOnly:
是否读
(1)读:查询操作。 写:添加删除操作
(2)readOnly默认值false
(3)设置为true之后就只可以查询了
4、rollbackFor:回滚
设置出现了哪些异常进行事务回滚
5、noRollbackFor:
设置出现了哪些异常不会进行事务回滚
恭喜你!Java-spring事务就完结啦