前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。

先让我们看代码吧!
以下代码为在“Spring3事务管理——基于tx/aop命名空间的配置”基础上修改。首先修改applicationContext.xml如下:

?
[html] view plain copy
  1. <!-- 定义一个数据源 -->
  2. <bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource">
  3. <property name="driverClassName" value="com.mysql.jdbc.Driver" />
  4. <property name="url" value="jdbc:mysql://localhost:3306/spring_test" />
  5. <property name="username" value="root" />
  6. <property name="password" value="root" />
  7. </bean>
  8. <!-- 定义JdbcTemplate的Bean -->
  9. <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
  10. p:dataSource-ref="dataSource">
  11. </bean>
  12. <!-- 配置事务管理器 -->
  13. <bean id="txManager"
  14. class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
  15. p:dataSource-ref="dataSource">
  16. </bean>
  17. <!-- enables scanning for @Transactional annotations -->
  18. <tx:annotation-driven transaction-manager="txManager" />
  19. <!-- 在该Bean的代码中标注@Transactional可以被事务管理器注入 -->
  20. <bean id="userScore"
  21. class="net.hingyi.springDemo.transaction.service.UserScoreServiceImpl"
  22. p:userScoreRepository-ref="userScoreRepository_jdbc" />
  23. <bean id="userScoreRepository_jdbc"
  24. class="net.hingyi.springDemo.transaction.repository.UserScoreRepositoryImpl"
  25. p:jdbcTemplate-ref="jdbcTemplate" />

实现类代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Transactional
publicclassUserScoreRepositoryImpl implementsUserScoreRepository {
    privateJdbcTemplate jdbcTemplate;
    @Override
    publicUserScore getUserSocore(String userNo) {
    finalUserScore us = newUserScore();
    ...
    returnus;
    }
    ...
}

OK了!以上就实现了简单的事务管理了。现在再稍微了解下@Transactional。
在配置文件中,默认情况下,<tx:annotation-driven>会自动使用名称为transactionManager的事务管理器。所以,如果定义的事务管理器名称为transactionManager,那么就可以直接使用<tx:annotation-driven/>。如下:

?
1
2
3
4
5
6
7
8
<!-- 配置事务管理器 -->
<beanid="transactionManager"
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
    p:dataSource-ref="dataSource">
</bean>
<!-- enables scanning for @Transactional annotations -->
<tx:annotation-driven/>

<tx:annotation-driven>一共有四个属性如下,

  • mode:指定Spring事务管理框架创建通知bean的方式。可用的值有proxy和aspectj。前者是默认值,表示通知对象是个JDK代理;后者表示Spring AOP会使用AspectJ创建代理
  • proxy-target-class:如果为true,Spring将创建子类来代理业务类;如果为false,则使用基于接口的代理。(如果使用子类代理,需要在类路径中添加CGLib.jar类库)
  • order:如果业务类除事务切面外,还需要织入其他的切面,通过该属性可以控制事务切面在目标连接点的织入顺序。
  • transaction-manager:指定到现有的PlatformTransaction Manager bean的引用,通知会使用该引用

@Transactional的属性

属性名

类型

说明

isolation

枚举org.springframework.transaction.annotation.Isolation的值

事务隔离级别

noRollbackFor

Class<? extends Throwable>[]

一组异常类,遇到时不回滚。默认为{}

noRollbackForClassName

Stirng[]

一组异常类名,遇到时不回滚,默认为{}

propagation

枚举org.springframework.transaction.annotation.Propagation的值

事务传播行为

readOnly

boolean

事务读写性

rollbackFor

Class<? extends Throwable>[]

一组异常类,遇到时回滚

rollbackForClassName

Stirng[]

一组异常类名,遇到时回滚

timeout

int

超时时间,以秒为单位

value

String

可选的限定描述符,指定使用的事务管理器

@Transactional标注的位置
@Transactional注解可以标注在类和方法上,也可以标注在定义的接口和接口方法上。
如果我们在接口上标注@Transactional注解,会留下这样的隐患:因为注解不能被继承,所以业务接口中标注的@Transactional注解不会被业务实现类继承。所以可能会出现不启动事务的情况。所以,Spring建议我们将@Transaction注解在实现类上。
在方法上的@Transactional注解会覆盖掉类上的@Transactional。

使用不同的事务管理器
如果我们要程序中使用多个事务管理器(主要是针对多数据源的情况),可以通过以下的方式实现:
Service代码:

?
1
2
3
4
5
6
7
8
9
10
11
publicclassMultiTxService {
    @Transactional("tran_1")
    publicvoidaddTest(intid){
         
    }
    @Transactional("tran_2")
    publicvoiddeleteTest(intid){
         
    }
}

applicationContext.xml配置如下:

?
1
2
3
4
5
6
7
8
9
10
<beanid="tran_1"
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
    p:dataSource-ref="dataSource">
    <qualifiervalue="tran_1"/>
</bean>
<beanid="tran_2"
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
    p:dataSource-ref="dataSource">
    <qualifiervalue="tran_2"/>
</bean>

经过以上的代码,每个事务都会绑定各自的独立的数据源,进行各自的事务管理。我们可以优化下以上代码,可以自定义一个绑定到特定事务管理器的注解,然后直接使用这个自定义的注解进行标识:

?
1
2
3
4
5
6
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Transactional("tran_1")
public@interfaceCustomerTransactional {
}

在Service代码中使用:

?
1
2
3
4
5
6
7
...
//使用名为tran_1的事务管理器
@CustomerTransactional
public void addTest(String str){
     
}

Spring在TransactionDefinition接口中规定了7种类型的事务传播行为,

它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播:

事务传播行为类型

事务传播行为类型

说明

PROPAGATION_REQUIRED

如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。

PROPAGATION_SUPPORTS

支持当前事务,如果当前没有事务,就以非事务方式执行。

PROPAGATION_MANDATORY

使用当前的事务,如果当前没有事务,就抛出异常。

PROPAGATION_REQUIRES_NEW

新建事务,如果当前存在事务,把当前事务挂起。

PROPAGATION_NOT_SUPPORTED

以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

PROPAGATION_NEVER

以非事务方式执行,如果当前存在事务,则抛出异常。

PROPAGATION_NESTED

如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类 似的操作。

spring 事务注解默认遇到throw new RuntimeException("...");会回滚
需要捕获的throw new Exception("...");不会回滚// 指定回滚
@Transactional(rollbackFor=Exception.class) public void methodName() {// 不会回滚throw new Exception("...");}
//指定不回滚
@Transactional(noRollbackFor=Exception.class)public ItimDaoImpl getItemDaoImpl() {// 会回滚throw new RuntimeException("注释");} // 如果有事务,那么加入事务,没有的话新建一个(不写的情况下)@Transactional(propagation=Propagation.REQUIRED) // 容器不为这个方法开启事务@Transactional(propagation=Propagation.NOT_SUPPORTED)// 不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务@Transactional(propagation=Propagation.REQUIRES_NEW) // 必须在一个已有的事务中执行,否则抛出异常@Transactional(propagation=Propagation.MANDATORY)// 必须在一个没有的事务中执行,否则抛出异常(与Propagation.MANDATORY相反)@Transactional(propagation=Propagation.NEVER) // 如果其他bean调用这个方法,在其他bean中声明事务,那就用事务.如果其他bean没有声明事务,那就不用事务.@Transactional(propagation=Propagation.SUPPORTS) /*public void methodName(){// 本类的修改方法 1update();// 调用其他类的修改方法otherBean.update();// 本类的修改方法 2update();}other失败了不会影响 本类的修改提交成功本类update的失败,other也失败*/
@Transactional(propagation=Propagation.NESTED)
// readOnly=true只读,能插入,但不能更新,删除
@Transactional (propagation = Propagation.REQUIRED,readOnly=true)
// 设置超时时间
@Transactional (propagation = Propagation.REQUIRED,timeout=30)
// 设置数据库隔离级别
@Transactional (propagation = Propagation.REQUIRED,isolation=Isolation.DEFAULT)

Spring 之注解事务 @Transactional相关推荐

  1. 仰天长啸 Spring 之注解事务 @Transactional

    spring 事务注解 默认遇到throw new RuntimeException("...");会回滚 需要捕获的throw new Exception("...&q ...

  2. 详解 spring 声明式事务(@Transactional)

    spring事务有2种用法:编程式事务和声明式事务. 编程式事务上一篇文章中已经介绍了,不熟悉的建议先看一下编程式事务的用法. 这篇主要介绍声明式事务的用法,我们在工作中基本上用的都是声明式事务,所以 ...

  3. Spring声明式事务@Transactional 注解参数详解

    @Transactional注解中常用参数说明 参数名称 功能描述 readOnly 该属性用于设置当前事务是否为只读事务,设置为true表示只读,false则表示可读写,默认值为false.例如:@ ...

  4. 框架源码专题:Spring声明式事务Transactional的原理

    文章目录 1. @Transactional的使用 2. spring事务的原理 2.1 开启事务,注册bean的后置处理器和相关bean对象,封装Advisor 2.2 匹配并创建动态代理 2.3 ...

  5. 【Spring】spring基于注解的声明式事务控制

    结构 domin package com.itheima.domain;import java.io.Serializable;public class Account implements Seri ...

  6. spring基于注解的声明式事务控制

    <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://mave ...

  7. Spring4.x()-Spring的Jdbc事务-注解

    Spring的Jdbc事务-注解 一.拷贝必要的jar包到工程的lib目录 二.创建spring的配置文件并导入约束 <?xml version="1.0" encoding ...

  8. spring注解事务使用总结

    在使用spring的注解事务的时候,需要考虑到事务的传播行为.遇到什么类型的异常时,事务才起作用.事务方法之间的嵌套调用时,怎么样才生效等等诸多问题.网上搜到很多的主要还是一堆理论文字描述,我这里给出 ...

  9. java day60【 Spring 中的 JdbcTemplate[会用] 、Spring 中的事务控制 、Spring5 的新特性[了解] 】...

    第1章 Spring 中的 JdbcTemplate[会用] 1.1JdbcTemplate 概述 1.2JdbcTemplate 对象的创建 1.3spring 中配置数据源 1.3.1 环境搭建 ...

最新文章

  1. 区块链学堂:区块链引子
  2. Python 之 matplotlib (十三) subplot分格显示
  3. 修复boot分区文件被删除的方法
  4. mysql性能结构优化原理_MySQL性能管理及架构设计(二):数据库结构优化、高可用架构设计、数据库索引优化...
  5. 抽象类和接口的共同点和区别
  6. sql server的跨库查询(简单实现)
  7. Python3.5 配置MySql数据库连接
  8. wraper for bootstrap3.0 + simple_form
  9. 【THUSC 2018】菜鸡互啄记
  10. JRebel-JVMTI [FATAL] Couldn‘t write to C:\Users\【完美解决方案】
  11. Virtual Box 报错,无法为虚拟电脑xxxx创建一个新任务
  12. Java游戏守卫者_守卫者 - Minecraft Wiki,最详细的官方我的世界百科
  13. pythonturtle写字_python用turtle写字
  14. iOS: HTTPS 与自签名证书
  15. [鲁林希] 学习动力篇
  16. 关于粒子图像测速实验的一些小经验
  17. 从Dump到POC系列一:Win32k内核提权漏洞分析
  18. 安全合规/ISO--3--ISO 27001控制目标与控制项介绍
  19. 浅析IPTV盒子和OTT盒子,如何选择?
  20. Python 爬虫的简单实例

热门文章

  1. CyclicBarrier-同步辅助类
  2. python中空格属于字符吗_举例说明python中空格是属于字符
  3. 【2019浙江省赛 - B】Element Swapping(思维,数学)
  4. Python求一个整数位数的方法
  5. 第九届(2018)蓝桥杯 山东省赛解题报告(题目+分析+代码)
  6. Apollo进阶课程⑰丨Apollo感知之旅——传感器选择和安装
  7. oracle mssql 实例,oracle,mysql,SqlServer三种数据库的分页查询的实例
  8. java猜数游戏图形界面_Java做一个猜数的小游戏
  9. 系统备份是对计算机硬件进行维户吗,计算机系统维护毕业论文_精品.doc
  10. wifisetting.java_Wifi 笔记 | 启动流程