学习笔记--Spring的事务控制
作者:互联网
1.编程式事务控制相关对象
1.1 PlatformTransactionManager
该接口是Spring的事务管理器,它里面提供了我们常用的操作事务的方法。
不同的技术,使用了不同的实现类实现该接口。
1.2 TransactionDefinition
是事务的定义信息对象。里面包含着事务的相关信息。里面有如下方法
方法 | 说明 |
int getIsolationLevel() | 获得事务的隔离级别 |
int getPropogationBehavior() | 获得事务的传播行为 |
int getTimeout() | 获得超时时间 |
boolean isReadOnly() | 是否只读 |
1.事务隔离级别:设置隔离级别,可以解决事务并发产生的问题,如脏读、不可重复读和虚读。
2.事务传播行为。
REQUIRED:如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中,一般的选择。
SUPPORTS:支持当前事务,如果当前没有事务,就以非事务方式执行(没有事务)。
1.3 TransactionStatus
该接口的是事务具体的运行状态。
方法 | 说明 |
boolean hasSavePoint() | 是否存储回滚点 |
boolean isCompleted() |
事务是否完成 |
boolean isNewTransaction() |
是否是新事务 |
boolean isRollbackOnly() | 事务是否滚回 |
被动封装事务状态信息。
2.基于XML的声明式事务控制
2.1 什么是声明式事务控制
采用声明的方式处理事务,这里说的声明,就是在配置文件中声明,在Spring配置文件中声明式的处理事务来代替代码式的处理事务。
作用:
事务管理不侵入开发的组件,因为事务管理是属于系统层面的服务,不是业务逻辑的一部分。
业务逻辑对象不会意识到正在事务管理之中。
(AOP的思想)
在不需要事务管理的时候,只需要在设定文件上修改一下,即可移除事务管理服务,无需改变代码。
注意:Srping声明式事务控制底层就是AOP
AOP的延展
2.2 声明式事务控制的实现
我们想对Service层下的transfer方法进行事务控制,目的是为了将转出和转入的操作作为一个事务整体,同成功同失败。
避免出现一方转出成功,一方转入失败仍然进行的问题。
public class AccountServiceImpl implements AccountService { private AccountDao accountDao; public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; } public void transfer(String outMan, String inMan, double money) { //开启事务 accountDao.out(outMan,money); int i = 1/0; accountDao.in(inMan,money); //提交事务 } }
我们对transfer中间进行自发的一个异常错误,我们需要做的是在执行转出方法前开启事务,在转入方法执行结束后结束事务,以达到统一的一个目的。
要达到Spring的事务控制,我们需要对xml进行控制。
<!-- 配置一个平台事务管理器 不同的技术实现用不同的事务管理器--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- 通知:事务的增强--> <tx:advice id="txAdive" transaction-manager="transactionManager"> <!-- 设置事务的属性信息 --> <tx:attributes> <tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" timeout="-1"/> <tx:method name="*" /> </tx:attributes> </tx:advice> <!-- 配置事务AOP的织入 --> <aop:config> <aop:advisor advice-ref="txAdive" pointcut="execution(* com.itheima.service.impl.*.*(..))"/> </aop:config>
第一个要配置的是平台事务管理器,不同的计算对应着不同的事务管理器类,所以要注意区分,里面需要注入DataSource属性,因为Spring通过数据库连接来控制事务。
第二个要配置的是事务的增强方法(与AOP不同的是不用自己定义增强类),由于用到了tx命名空间,所以使用前要引入tx的命名空间。这里配置了用的平台事务管理器,还有对不同方法的不同事务参数配置。
第三个要配置的是事务AOP的织入,与AOP一样,pointcut里面写的是对什么范围的业务方法使用业务增强。
2.3 切点方法的事务参数配置
<!-- 通知:事务的增强--> <tx:advice id="txAdive" transaction-manager="transactionManager"> <!-- 设置事务的属性信息 --> <tx:attributes> <tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" timeout="-1"/> <tx:method name="*" /> </tx:attributes> </tx:advice>
name:切点方法名称
isolation:事务的隔离级别
propagation:事务的传播行为
timeout:超时时间
read-only:是否只读
3.基于注解的声明式事务控制
3.1 快速实现
主要是将以下配置改成注解方式。
<!-- 通知:事务的增强--> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <!-- 设置事务的属性信息 --> <tx:attributes> <tx:method name="transfer" isolation="REPEATABLE_READ" propagation="REQUIRED" read-only="false" timeout="-1"/> <tx:method name="*" /> </tx:attributes> </tx:advice> <!-- 配置事务AOP的织入 --> <aop:config> <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.itheima.service.impl.*.*(..))"/> </aop:config>
这些全部在业务方法类上进行,也就是Service层。
@Service("accountService") @Transactional(isolation = Isolation.READ_COMMITTED) public class AccountServiceImpl implements AccountService { @Autowired private AccountDao accountDao; @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED) public void transfer(String outMan, String inMan, double money) { //开启事务 accountDao.out(outMan,money); int i = 1/0; accountDao.in(inMan,money); //提交事务 } // @Transactional() public void xxx(){} }
使用@Transactional注解来完成,注解可用的属性同xml配置方式。
如果该注解出现在整个Service类上,表明该类的所有业务方法都采用该注解所对应的值来配置。
如果该注解出现在某个业务方法上,表明该业务方法的某个配置。
如果都有,服从就近原则。
xml配置文件要开启事件的注解驱动
<tx:annotation-driven transaction-manager="transactionManager"/>
标签:事务,accountDao,--,Spring,笔记,AOP,注解,方法,public 来源: https://www.cnblogs.com/xiaochaoheni/p/15959677.html