本篇文章只涉及spring事务的配置,不进行事务的介绍。

spring通过PlatformTransactionManager接口作为事务管理器来进行事务的管理,它本身并不进行事务的创建以及相关操作,它就相当于事务管理的容器,里面放的是事务。事务使用有编程式事务和声明式事务,现在一般情况下都是使用声明式事务。

声明式事务使用方法:

1、在配置的xml文件中使用AOP模式来进行事务声明,如下所示

    <bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="interceptorPointCut"
expression="execution(* com.test.service.impl.*.*(..))" />
<aop:advisor advice-ref="txAdvice" pointcut-ref="interceptorPointCut" />
</aop:config>

2、使用注解形式进行事务声明,如下所示:

第一步:在xml配置文件中加入如下配置

<!-- 启动声明式注解 -->
<tx:annotation-driven transaction-manager="transactionManager" />

或者在被@configuration注解注释的类上添加@EnableTransactionManagement注解

第二步:在需要添加事务的类或方法上添加@Transactional注解,注解可以设置value(用来设置数据源)、transactionManager(同value作用相同)、propagation(设置事务的传播行为,使用枚举Propagation来选择值,默认是REQUIRED)、isolation(设置事务的隔离机制,使用枚举Isolation来选择值,默认是底层数据库支持的事务的默认隔离机制)、timeout(设置事务的超时时间,可以使用TransactionDefinition接口提供的值,默认值为-1)、readOnly(布尔值,设置事务为只允许读,不进行修改操作,如果是只有读的操作可以设置为true,官方解释设置为true时,会在运行时进行相应的优化,但是并不能保证进行修改操作会失败)、rollbackFor(设置进行事务回滚的异常类类型)、rollbackForClassName(设置进行事务回滚的异常类类名)、noRollbackFor(设置不会进行事务回滚的异常类类型)、noRollbackForClassName(设置不会进行事务回滚的异常类类名)

即使没有设置rollbackFor、rollbackForClassName的值,spring框架在我们调用的方法发生运行时异常的时候会进行事务回滚操作。

3、利用AOP的around类型的advice进行事务声明,如下所示

@Aspect
@Component
public class TransactionalAop { @Autowired
PlatformTransactionManager transactionManager; @Around("execution(* com.test.service.impl.*.*(..))")
public void aroundMethod(ProceedingJoinPoint pjp) throws Throwable {// // 利用spring框架提供的事务模板类进行事务操作
// TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
// transactionTemplate.execute((status) -> {
// Object result = null;
// try {
// result = pjp.proceed();
// } catch (Throwable e) {
// if (e instanceof RuntimeException) {
// throw (RuntimeException)e;
// }
// if (e instanceof Error) {
// throw (Error)e;
// }
// throw new RuntimeException(e);
// }
// return result;
// }); // 手动创建事务(同时开启事务)并根据方法调用结果进行事务回滚或者提交
TransactionStatus transaction = transactionManager.getTransaction(new DefaultTransactionDefinition());
try {
pjp.proceed();
} catch (Throwable e) {
transactionManager.rollback(transaction);
throw e;
}
transactionManager.commit(transaction);
}
}

如上所示,我们可以利用spring提供的TransactionTemplate类来进行事务的相关操作,但是这里使用有个小缺陷,就是execute(TransactionCallback<T> action)方法里的参数action中的doInTransaction(TransactionStatus status)方法没有显式抛出异常,所以我们只能在doInTransaction(TransactionStatus status)方法中抛出运行时异常或Error来进行事务的回滚。如果是自己手动进行事务开启、提交、回滚就不会存在这个问题,如上所示,利用PlatformTransactionManager接口的getTransaction(@Nullable TransactionDefinition definition)方法来进行事务的开启,最后根据方法的执行结果来进行事务提交或回滚操作。

综合:

第一种方法是老式的xml配置文件进行事务配置的方法,需要用到xml配置文件,在如今springboot肆意横行的时代(springboot允许我们加载xml配置文件,但是如果还在使用xml配置文件不是又回去了吗?!),这种配置方式已经算是落伍了。

第二种方法是基于注解进行事务配置的方法,算是比较方便。优点是:事务管理的粒度比较细,@Transactional既可以用在类上也可以用在方法上;缺点:至少每个业务逻辑的类都要用到@Transactional注解。

第三种方法是利用aop的动态代理原理,在方法调用之前进行事务开启,根据方法执行结果来进行事务的相关操作。优点:事务统一管理,不在需要每个类或方法上添加@Transactional注解;缺点:事务管理的粒度比较粗。

最新文章

  1. Mysql操作语句
  2. 用CSS正确显示人民币符号的HTML转义字符
  3. [Java拾遗一] XML的书写规范与解析.
  4. dubbo 2.5.4-SNAPSHOT dubbo-admin 报错
  5. apache配置虚拟目录
  6. Android IOS WebRTC 音视频开发总结(四三)-- 诚信交易案例分享
  7. 【采集】php str_replace
  8. 关于android开发添加菜单XML文件之后无法在R.java中生成ID的问题
  9. UIView的setNeedsLayout, layoutIfNeeded 和 layoutSubviews 方法之间的关系解释
  10. openssh-clients(CentOS 7 自带的SSH客户端)
  11. PHP学习过程_Symfony_(1)
  12. SimplePath 使用心得
  13. 基于SSM实现的简易员工管理系统
  14. CSS实现文字换行
  15. Mahout文本向量化
  16. js动画最佳实现——requestAnimationFrame
  17. SimpleDateFormat未抛出ParseException
  18. UIScrollView的判断位置的属性如下:
  19. 如何查找论文是否被SCI,EI检索(转)
  20. MySQL---3、常用命令大全

热门文章

  1. search(5)- elastic4s-构建索引
  2. AJ学IOS 之微博项目实战(8)用AFNetworking和SDWebImage简单加载微博数据
  3. SpringBoot连接Redis服务出现DENIED Redis is running in protected mode because protected mode is enabled
  4. Roles on a Machine Learning Project (机器学习项目中的角色)
  5. Equalizing by Division
  6. 14. 最长公共前缀----LeetCode
  7. 掌握MySQL连接查询到底什么是驱动表
  8. Java讲解RPC的基本实现
  9. python学习12类
  10. 点击 QTableView,触发事件