10、声明式事务
admin
2023-08-15 20:42:07
0

一、基础回顾 1、导入相关的依赖

org.springframework spring-jdbc 4.3.0.RELEASE c3p0 c3p0 0.9.1.2 mysql mysql-connector-java 5.1.44

2、进行相关的配置操作
  • 配置数据源
  • JdbcTemplate操作数据
  • @EnableTransactionManagement 开启基于注解的事务管理功能
  • 配置事务管理器来控制事务
@EnableTransactionManagement @ComponentScan("com.qiu.tx") @Configuration public class TxConfig {//数据源 @Bean public DataSource dataSource() throws Exception{ ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setUser("root"); dataSource.setPassword("123456"); dataSource.setDriverClass("com.mysql.jdbc.Driver"); dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test"); return dataSource; }@Bean public JdbcTemplate jdbcTemplate() throws Exception{ //Spring对@Configuration类会特殊处理;给容器中加组件的方法,多次调用都只是从容器中找组件 JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource()); return jdbcTemplate; }//注册事务管理器在容器中 @Bean public PlatformTransactionManager transactionManager() throws Exception{ return new DataSourceTransactionManager(dataSource()); }}

3、给方法上标注 @Transactional 表示当前方法是一个事务方法
  • UserDao
@Repository public class UserDao {@Autowired private JdbcTemplate jdbcTemplate; public void insert(){ String sql = "INSERT INTO `tbl_user`(username,age) VALUES(?,?)"; String username = UUID.randomUUID().toString().substring(0, 5); jdbcTemplate.update(sql, username,19); }}

  • UserService
@Service public class UserService { @Autowired private UserDao userDao; @Transactional public void insertUser(){ userDao.insert(); //otherDao.other(); xxx System.out.println("插入完成..."); //失败则回滚否则成功插入数据库 int i = 10/0; } }

二、原理
  • 前面知道了@EnableXXX注解主要作用是导入相应的功能类,因此从这个注解入手
1、@EnableTransactionManagement
//开始spring事物管理 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented //给容器导入TransactionManagementConfigurationSelector @Import(TransactionManagementConfigurationSelector.class) public @interface EnableTransactionManagement { //默认java的jdk代理方式 boolean proxyTargetClass() default false; //默认事物以代理方式进行 AdviceMode mode() default AdviceMode.PROXY; int order() default Ordered.LOWEST_PRECEDENCE; }

2、TransactionManagementConfigurationSelector类
public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector { @Override protected String[] selectImports(AdviceMode adviceMode) { switch (adviceMode) { case PROXY: //默认导入AutoProxyRegistrar和ProxyTransactionManagementConfiguration两个组件 return new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()}; case ASPECTJ: //如果是ASPECTJ则导入其他 return new String[] {TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME}; default: return null; } }}

2.1AutoProxyRegistrar
public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar {private final Log logger = LogFactory.getLog(getClass()); //根据给定的注解注册相应的bean @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { boolean candidateFound = false; Set annoTypes = importingClassMetadata.getAnnotationTypes(); for (String annoType : annoTypes) { AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annoType); Object mode = candidate.get("mode"); Object proxyTargetClass = candidate.get("proxyTargetClass"); if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() && Boolean.class == proxyTargetClass.getClass()) { candidateFound = true; if (mode == AdviceMode.PROXY) { //给容器中注册一个 InfrastructureAdvisorAutoProxyCreator 后置处理器组件 //InfrastructureAdvisorAutoProxyCreator 利用后置处理器机制在对象创建以后,包装对象, //返回一个代理对象(增强器),代理对象执行方法利用拦截器链进行调用; AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry); if ((Boolean) proxyTargetClass) { AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry); return; } } } } if (!candidateFound) { String name = getClass().getSimpleName(); logger.warn(String.format("%s was imported but no annotations were found " + "having both 'mode' and 'proxyTargetClass' attributes of type " + "AdviceMode and boolean respectively. This means that auto proxy " + "creator registration and configuration may not have occured as " + "intended, and components may not be proxied as expected. Check to " + "ensure that %s has been @Import'ed on the same class where these " + "annotations are declared; otherwise remove the import of %s " + "altogether.", name, name, name)); } }}

2.2ProxyTransactionManagementConfiguration
  • 是一个配置类,主要给容器中注册事务增强器
@Configuration public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration { //1、事务增强器要用事务注解的信息, @Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME) @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() { BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor(); advisor.setTransactionAttributeSource(transactionAttributeSource()); advisor.setAdvice(transactionInterceptor()); advisor.setOrder(this.enableTx.getNumber("order")); return advisor; } //2.利用AnnotationTransactionAttributeSource解析事务注解 @Bean @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public TransactionAttributeSource transactionAttributeSource() { return new AnnotationTransactionAttributeSource(); } //3.事务拦截器保存了事务属性信息,事务管理器等信息 @Bean @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public TransactionInterceptor transactionInterceptor() { TransactionInterceptor interceptor = new TransactionInterceptor(); interceptor.setTransactionAttributeSource(transactionAttributeSource()); if (this.txManager != null) { interceptor.setTransactionManager(this.txManager); } return interceptor; } }

  • 事务拦截器工作原理
【10、声明式事务】1、在目标方法执行的时候,执行拦截器链,对事物进行拦截
2、先获取事务相关的属性
3、再获取PlatformTransactionManager,如果事先没有添加指定任何transactionmanger,最终会从容器中按照类型获取一个PlatformTransactionManager;
4、执行目标方法。如果异常,获取到事务管理器,利用事务管理回滚操作,如果正常,利用事务管理器,提交事务。

相关内容

热门资讯

超... 本文目录导航: 超级云计算是什么 怎么做难看的PPT 1、...
谢... 本文目录导航: 请问云主机是什么 云主机有什么好处 具体的教程,谢谢! 云...
w... 本文目录导航: wps是什么意思 ppt的新配置designer和morp...
大... 本文目录导航: 大专学什么专业务工率高? 未来十年务工率最高的几大专业都是...
软... 本文目录导航: 软件技术专升本可以报什么专业 云计算专升本可以报医学吗 ...
云... 本文目录导航: 云计算务工前景 云计算务工方向及前景怎样样 ...
学... 本文目录导航: 学云计算进去无能嘛 云计算技术与运行是干什么的 ...
中... 本文目录导航: 如何了解云计算,中国的云计算产业开展现状如何 云计算未来几...
云... 本文目录导航: 云计算1+x证书含金量 云计算须要考什么证书 ...
云... 本文目录导航: 云计算股票龙头股票有哪些? 普通云计算概念龙头股有哪些?...
大... 本文目录导航: 大专云计算技术运行务工方向 大专毕业证上是物联网,实践学习...
大... 本文目录导航: 大数据云计算有必要升本吗 内蒙古大专云计算技术与运行专业升...
9... 本文目录导航: 99%学霸假期逆袭必看网站 99%学霸假期逆袭必看网站 ...
云... 本文目录导航: 云计算属于哪个专业 云计算属于什么专业 计...
计... 本文目录导航: 计算机二级MSOffice上机操作题及答案 想做一篇关于解...
A... 本文目录导航: AI能否会彻底扭转上流职业市场,如律师、会计师和医师? A...
人... 本文目录导航: 人工智能芯片产业链有哪些? 更多本行业钻研剖析详见前瞻产业...
人... 本文目录导航: 人工智能会带来哪些风险? 或许有一天,人工智能机器人将取代...
a... 本文目录导航: ai智能写作软件哪个好 ai智能写作软件有哪些?ai智能对...
自... 本文目录导航: 自考本科计算机专业难吗 自考计算机专业须要考哪些科目 ...