Spring 之注解事务 @Transactional

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

先让我们看代码吧!
以下代码为在“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.    
  9. <!-- 定义JdbcTemplate的Bean -->  
  10. <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"  
  11.         p:dataSource-ref="dataSource">  
  12. </bean>  
  13.    
  14. <!-- 配置事务管理器 -->  
  15. <bean id="txManager"  
  16.         class="org.springframework.jdbc.datasource.DataSourceTransactionManager"  
  17.         p:dataSource-ref="dataSource">  
  18. </bean>  
  19.    
  20. <!-- enables scanning for @Transactional annotations -->  
  21. <tx:annotation-driven transaction-manager="txManager" />  
  22.    
  23. <!-- 在该Bean的代码中标注@Transactional可以被事务管理器注入 -->  
  24. <bean id="userScore"  
  25.         class="net.hingyi.springDemo.transaction.service.UserScoreServiceImpl"  
  26.         p:userScoreRepository-ref="userScoreRepository_jdbc" />  
  27.    
  28. <bean id="userScoreRepository_jdbc"  
  29.         class="net.hingyi.springDemo.transaction.repository.UserScoreRepositoryImpl"  
  30.         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)
复制代码

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/450824.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

超级程序员神话

摘要&#xff1a;大部分的程序员在思想里都会某种程度的承认&#xff0c;承认自己只是一个普通的程序员&#xff0c;但这世界上确实有一些超级程序员&#xff0c;在一个为企业开发应用的程序员和一个为谷歌写搜索算法的程序员之间&#xff0c;或和一个开发用来控制读写头从磁盘…

HashMap30连问,彻底搞懂HashMap

文章目录一、背景知识1、什么是Map&#xff1f;2、什么是Hash&#xff1f;3、什么是哈希表&#xff1f;4、什么是HashMap?5、如何使用HashMap&#xff1f;6、HashMap有哪些核心参数&#xff1f;7、HashMap与HashTable的对比&#xff1f;8、HashMap和HashSet的区别&#xff1f;…

如何使用postman做接口测试

1、get请求传参 只要是get请求都可以在浏览器中直接发&#xff1a; 在访问地址后面拼 ?keyvalue&keyvalue 例如&#xff1a;在浏览器中直接输入访问地址&#xff0c;后面直接拼需要传给服务器的参数http://api.nnzhp.cn/api/user/stu_info?stu_name小黑2、post请求&…

【狂神说】分析前后端分离开源项目?

文章目录1.如何分析开源项目项目简介项目源码2.观察开源项目3.开源项目下载4.跑起来是第一步5.前后端分离项目固定套路6.如何找到一个开源项目1.如何分析开源项目 学习的方式&#xff1a; 不知道这个代码怎么来的这个代码跑不起来这个项目对我们有什么帮助&#xff0c;不会模…

设计公共API的六个注意事项

摘要&#xff1a;俗话说&#xff1a;“好东西就要贡献出来和大家一起分享”&#xff0c;尤其是在互联网业务高度发达的今天&#xff0c;如果你的创业公司提供了一项很酷的技术或者服务&#xff0c;并且其他用户也非常喜欢该产品&#xff0c;在这种情况下&#xff0c;最好的解决…

go 交叉编译

golang中windows交叉编译 env GOOSlinux GOARCHamd64 go build .打包镜像 FROM alpineMAINTAINER "congge"ADD ./casino_niuniu /usr/local/casino_niuniu/bin/casino_niuniu ADD ./templates /usr/loca/lcasino_niuniu/bin/templates ADD ./public /usr/local/casin…

P3193 [HNOI2008]GT考试

传送门 容易看出是道DP 考虑一位一位填数字 设 f [ i ] [ j ] 表示填到第 i 位&#xff0c;在不吉利串上匹配到第 j 位时不出现不吉利数字的方案数 设 g [ i ] [ j ] 表示不吉利串匹配到第 i 位&#xff0c;再添加一个数字&#xff0c;使串匹配到第 j 位的方案数 那么方程显然为…

SQLserver数据库反编译生成Hibernate实体类和映射文件

一、建立项目和sqlserver数据库 eclipse&#xff0c;我使用的版本是neon3 二、Data Source Explorer 选择OK 在data source Explorer的Database Connections 选择New 填写好General的连接信息 新建New Driver Definition 填写完选择OK 选择刚才的Drivers Test Connetion测试 N…

最受欢迎的5大Linux发行版

摘要&#xff1a;要统计有多少人在使用那款Linux发行版几乎是不可能的事情&#xff0c;但我们可以使用一些在线分析工具来大概地看看哪些Linux发行版更受欢迎。 Google Trends的数据显示&#xff0c;Ubuntu用户正在流向Mint&#xff0c;但依然在各方面都比其它Linux发行版更有优…

使用IntelliJ IDEA 配置Maven(入门)

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 1. 下载Maven 官方地址&#xff1a;http://maven.apache.org/download.cgi 解压并新建一个本地仓库文件夹 2.配置本地仓库路径 3.配…

为什么程序员不擅长估算时间?

摘要&#xff1a;时间估算是困难的&#xff0c;每一个程序员都有一个现实的估计区间&#xff0c;低于这个区间的估计意味着&#xff08;构件&#xff0c;测试&#xff0c;检查代码的&#xff09;时间开销被低估了&#xff0c;超过这个区间的估计意味着这个任务太大而很难预估。…

red hat enterprise linux 7关闭防火墙的方法

2019独角兽企业重金招聘Python工程师标准>>> red hat enterprise linux 7发布后&#xff0c;发现防火墙也变了&#xff0c;如何关闭防火墙呢&#xff0c;下面是方法 1.查看firewall的状态 [rootsztech7 ~]# systemctl status firewalld firewalld.service - firewal…

IOS —— 网络那些事(上) - http协议

作为一名并不太合格的程序员&#xff0c;今天要分享学习的成果&#xff0c;竟然讲的是网络相关HTTP协议的事情。&#xff08;也算是复习了&#xff09; 乍看HTTP协议的内容着实是十分复杂的&#xff0c;涉及到十分多互联网"底层"框架的东西。今天就先撇开这部分详细内…

老派程序员——徒手实现伟大成就

摘要&#xff1a;本文介绍了三位非常著名的程序员&#xff1a;Ken Thompson,Joe Armstrong 和 Jamie Zawinski&#xff0c;他们是如何发明一门新语言&#xff0c;他们开发软件时会像我们一样使用当今流行的开发工具吗&#xff1f;当读Peter Seibel的精彩著作《编程人生:15位软件…

互联网大厂项目研发流程

文章目录阶段一&#xff1a;阶段二&#xff1a;阶段三&#xff1a;阶段四&#xff1a;阶段五&#xff1a;开发人员&#xff1a;测试人员&#xff1a;设计师&#xff1a;阶段六&#xff1a;阶段七&#xff1a;总结&#xff1a;本文章学习自&#xff1a;https://www.bilibili.com…

解决 java.lang.IllegalArgumentException: Repository interface must not be null on initialization!

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 报错&#xff1a;Caused by: java.lang.IllegalArgumentException: Repository interface must not be null on initialization! Cause…

【狂神说】JVM

文章目录1.JVM的位置2.JVM的体系结构3.类加载器4.双亲委派机制&#xff08;重要&#xff09;5.沙箱安全机制(了解)6.native&#xff08;核心&#xff09;7.PC寄存器&#xff08;了解&#xff09;8.方法区9.栈10.三种JVM11.堆&#xff08;Heap&#xff09;12.新生区、老年区13.永…

我们真的需要统一的编程规范?

摘要&#xff1a;仁者见仁智者见智&#xff0c;编码风格的不同&#xff0c;对项目也会有不同的影响&#xff0c;统一的编码规范有益于项目的维护。俗话说&#xff0c;没有规矩不成方圆&#xff0c;在2004年&#xff0c;UNIX创始人之一的Ken Arnold就发表了一篇很幽默文章&#…

百度云重磅发布ABC 3.0 尹世明如何诠释百度云的“新”打法

雷锋网9月4日消息&#xff0c;2018百度云智峰会正式召开&#xff0c;百度总裁张亚勤发表题为《新技术驱动&#xff0c;全面进入Cloud2.0》的演讲并表示&#xff0c;经历了PCClient/Server到MobileCloud 1.0&#xff0c;再到如今的AICloud 2.0过程&#xff0c;新技术推动云计算产…

开发人员眼中最好的代码编辑器是谁?

摘要&#xff1a;对开发人员来讲&#xff0c;开发工具就好比战场上的“兵器”&#xff0c;不同领域的开发人员他们所使用的“兵器”也不完全相同&#xff0c;本文从友好性、功能性、扩展等多方面总结了最受开发人员欢迎的“兵器”。你最爱的那个在这里吗&#xff1f; 如果我们把…