一、什么是事务
- 事务是将一系列的sql操作封装在一个单元中,这个单元叫做事务,事务要嘛都做,要嘛不做,事务可以撤销。
- 我们在实际业务场景中,经常会遇到数据频繁修改读取的问题。在同一时刻,不同的业务逻辑对同一个表数据进行修改,这种冲突很可能造成数据不可挽回的错乱,所以我们需要用事务来对数据进行管理。
- 事务(Transaction)是并发控制单位,是用户定义的一个操作序列,这些操作要么都做,要么都不做,是一个不可分割的工作单位。
-
)典型场景:银行转账有以下两个操作* lucy 转账 100 元 给 mary* lucy 少 100 , mary 多 100
二、事务的四个特性(ACID)
(1)原子性
(2)一致性
- 拿转账来说,假设用户A和用户B两者的钱加起来一共是5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是5000,这就是事务的一致性。
(3)隔离性
(4)持久性
三、准备工作:搭建事务操作环境(以银行A给B转钱为例)
javaEE中一般分为三层:WEB层(视图操作)、Service层(业务逻辑操作)、Dao层(数据库操作)
1、创建一个表-book_account:
2、手动添加两条记录
3、创建 T_service,T_Dao和T_DaoImp,完成对象创建和注入关系
(1)T_service 注入属性:T_DaoImp对象,在T_DaoImp注入 JdbcTemplate,在 JdbcTemplate 注入 DataSource
(2)在T_DaoImp实现两个方法:多钱和少钱的方法
(3)在T_service 创建方法(转账的两个方法),并分别调用T_DaoImp实现两个方法:多钱和少钱的方法
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
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/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 数据库连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
destroy-method="close">
<property name="url" value="jdbc:mysql:///user_db" /><!--对应SQLyog里的数据库-->
<property name="username" value="root" /> <!-- 用户名 -->
<property name="password" value="4.233928" /> <!-- 密码 -->
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
</bean>
<!-- JdbcTemplate对象 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--注入dataSource属性,相当于把jdbcTemplate和数据库联系在一起-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 组件扫描 -->
<context:component-scan base-package="Transection"></context:component-scan>
</beans>
四、事务操作
- 上面代码,如果正常执行没有问题的,但是如果代码执行过程中出现异常,有问题。如下图,则只会执行了reduceMoney(),没有执行addMoney()。
事务操作大概流程:
1 、事务添加到 JavaEE 三层结构里面 Service 层(业务逻辑层)2 、在 Spring 进行事务管理操作( 1 )有两种方式: 编程式事务管理和声明式事务管理(开发都使用声明式事务管理,方便)3 、声明式事务管理( 1 )基于注解方式(使用)( 2 )基于 xml 配置文件方式4 、在 Spring 进行声明式事务管理,底层使用 AOP 原理5 、 Spring 事务管理 API( 1 )提供一个接口,代表事务管理器,这个接口针对不同的框架提供不同的实现类******我们用的就是 DataSourceTransactionManager 实现类
五、基于 注解的 声明式 事务管理操作
1、在上面的xml文件基础上添加事务管理器<bean>对象
2、在上面的xml文件基础上引入名称空间,开启事务注解
xmlns:tx="http://www.springframework.org/schema/tx"
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
3、完整配置文件
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 数据库连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
destroy-method="close">
<property name="url" value="jdbc:mysql:///user_db" /><!--对应SQLyog里的数据库-->
<property name="username" value="root" /> <!-- 用户名 -->
<property name="password" value="4.233928" /> <!-- 密码 -->
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
</bean>
<!-- JdbcTemplate对象 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<!--注入dataSource属性,相当于把jdbcTemplate和数据库联系在一起-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 组件扫描 -->
<context:component-scan base-package="Transection"></context:component-scan>
<!--创建事务管理器对象(类来自于jar包)-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入数据源,即上面的数据库连接池对象-->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--开启事务注解-->
<!--transaction-manager="transactionManager"表示你选择的事务管理器,即上面的事务管理器对象-->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
</beans>
4、在 T_service 类上面(或者T_ service 类里面方法上面)添加事务注解 @Transactional
(
1
)
@Transactional
,这个注解添加到类上面,也可以添加方法上面
(
2
)如果把这个注解添加类上面,这个类里面所有的方法都添加事务
(
3
)如果把这个注解添加方法上面,为这个方法添加事务
六、声明式事务管理参数配置