大家好,我是被白菜拱的猪。
一个热爱学习废寝忘食头悬梁锥刺股,痴迷于girl的潇洒从容淡然coding handsome boy。
这里写目录标题
一、写在前言
二、声明式事务
(一)事务的四大特性
事务的底层是AOP原理,有ACID(原子性,一致性,隔离性,持久性)Spring有事务管理器,是一个借口为每一个框架提供了实现类。
● 原子性(Atomicity):操作这些指令时,要么全部执行成功,要么全部不执行。只要其中一个指令执行失败,所有的指令都执行失败,数据进行回滚,回到执行指令前的数据状态。
● 一致性(Consistency):事务的执行使数据从一个状态转换为另一个状态,但是对于整个数据的完整性保持稳定。
eg:拿转账来说,假设用户A和用户B两者的钱加起来一共是20000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是20000,这就是事务的一致性。
● 隔离性(Isolation):隔离性是当多个用户并发访问数据库时,比如操作同一张表时,数据库为每一个用户开启的事务,不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。
即要达到这么一种效果:对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执行。
● 持久性(Durability):当事务正确完成后,它对于数据的改变是永久性的。
eg: 例如我们在使用JDBC操作数据库时,在提交事务方法后,提示用户事务操作完成,当我们程序执行完成直到看到提示后,就可以认定事务以及正确提交,即使这时候数据库出现了问题,也必须要将我们的事务完全执行完成,否则就会造成我们看到提示事务处理完毕,但是数据库因为故障而没有执行事务的重大错误。
(二)注解声明式事务使用
编程式事务是怎么使用呢?首先开启事务,然后业务代码,然后提交事务,业务代码出现异常则回滚事务,但是这样比较麻烦,Spring采用声明式事务,一个注解搞定。
1、Spring配置文件创建事务处理器,指定数据源
2、在Spring配置文件中引入名称空间tx
3、开启事务注解
4、在方法或类上写@Transactional
下面对@Transactional注解中的方法进行讲解:
1、事务传播行为(propagation)
Spring中有七种传播行为,就是当在一个方法中调用另一个方法时Spring是如何处理的。我们这里介绍常见的两种:
- REQUIRED:先看看当前存不存在事务,假如存在事务的话就加进去,不存在就新建一个事务。
- REQUIRES_NEW:不管当前有没有事务,都会创建一个新事物
事务传播行为类型 | 说明 |
---|---|
PROPAGATION_REQUIRED | 如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。 |
PROPAGATION_SUPPORTS | 支持当前事务,如果当前没有事务,就以非事务方式执行。 |
PROPAGATION_MANDATORY | 使用当前的事务,如果当前没有事务,就抛出异常。 |
PROPAGATION_REQUIRES_NEW | 新建事务,如果当前存在事务,把当前事务挂起。 |
PROPAGATION_NOT_SUPPORTED | 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 |
PROPAGATION_NEVER | 以非事务方式执行,如果当前存在事务,则抛出异常。 |
PROPAGATION_NESTED | 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。 |
2、事务隔离级别(isolation)
我们前面讲过事务的性质ACID,所谓隔离性就是多个事务开启,互不影响,假如没有隔离性就会出现一系列的问题:脏读、不可重复读、虚(幻)读。
- 脏读:就是一个未提交的事务读取到另一个未提交事务的数据。例如两个人(事务)都对同一个数据进行操作,小明想把它+50,小红想把它从100改到500,然后小明读取数据读到了小红改过的500,但小红有可能进行回滚,所以原先应该是100,而不是500。ai,本来读的不是你,然后读到了你,这不就是读错了嘛。
- 不可重复读:一个未提交事务读取到另一提交事务修改数据。
- 虚读:一个未提交数据读取到另一个提交事务添加数据。
那么如何避免这种情况产生呢,事务为我们提供了隔离级别,读未提交,读提交,重复读,序列化。
@Transactional(isolation = Isolation.READ_COMMITTED)
3、超时时间(timeout)
规定事务在设置的时间内提交,假如没有提交就回滚,默认值为-1,即不设置时间。
4、是否只读(readOnly)
read就是读即查询操作readOnly默认为false,即只能进行查询操作,readOnly = true,即增删改查都可以。
5、rollbackFor
设置出现哪些异常事务回滚
6、norollbackFor
设置出现哪些异常事务不回滚。
(三)事务管理-XML方式
分为三步:
第一步: 配置事务管理器。
第二步: 配置切面。
第三步: 配置切入点和切面。
<! -- 1 创建事务管理器 -- >
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><! -- 注入数据源
-- > <property name="dataSource" ref="dataSource"></property>
</bean>
<! -- 2 配置通知 -- >
<tx:advice id="txadvice"><! -- 配置事务参数 -- >
<tx:attributes><! -- 指定哪种规则的方法上面 添加事务 -- >
<tx:method name="accountMoney" propagation="REQUIRED"/>
<! --
<tx:method name="account*"/>
-- >
</tx:attributes>
</tx:advice>
<! -- 3 配置切入点和切面 -- >
<aop:config><! -- 配置切入点 -- >
<aop:pointcut id="pt" expression="execution(* com.atguigu.spring5.service.UserService.*(..))"/>
<! -- 配置切面 -- >
<aop:advisor advice-ref="txadvice" pointcut-ref="pt"/>
</aop:config>
三、结束语
最近学习超级懈怠啊,看来情感对学习影响还是相当大的…Spring基础部分就告一段落,IOC,AOP,事务,下面进行SpringBoot的学习。