原文地址:http://hwak.iteye.com/blog/1611970

1. 在需要事务管理的地方加@Transactional 注解。@Transactional 注解可以被应用于接口定义和接口方法、类定义和类的 public 方法上 。

2. @Transactional 注解只能应用到 public 可见度的方法上 。 如果你在 protected、private 或者 package-visible 的方法上使用 @Transactional 注解,它也不会报错, 但是这个被注解的方法将不会展示已配置的事务设置。

3. 注意仅仅 @Transactional 注解的出现不足于开启事务行为,它仅仅 是一种元数据。必须在配置文件中使用配置元素,才真正开启了事务行为。

4. 通过 元素的 "proxy-target-class" 属性值来控制是基于接口的还是基于类的代理被创 建。 如果 "proxy-target-class" 属值被设置为 "true",那么基于类的代理将起作用(这时需要CGLIB库cglib.jar在CLASSPATH中)。如果 "proxy-target-class" 属值被设置为 "false" 或者这个属性被省略,那么标准的JDK基于接口的代理将起作用。

  1. <!-- JTA事务(非分布式事务), 事务配置的时候 ,不能指定dataSource属性(分布式事务,是有全局事务来管理数据库链接的)-->
  2. <!-- 标准的JDK基于接口的代理将起作用 -->
  3. <!-- aop切面 -->
  4. <aop:aspectj-autoproxy proxy-target-class="false" />
  5. <!-- 基于类的代理将起作用 ,同时 cglib.jar必须在CLASSPATH中 -->
  6. <!-- aop切面 -->
  7. <aop:aspectj-autoproxy proxy-target-class="true" />

注 解@Transactional cglib与java动态代理最大区别是代理目标对象不用实现接口, 那么注解要是写到接口方法上,要是使用cglib代理,这是注解事物就失效了,为了保持兼容注解最好都写到实现类方法上。

5. Spring团队建议在具体的类(或类的方法)上使用 @Transactional 注解,而不要使用在类所要实现的任何接口上 。在接口上使用 @Transactional 注解,只能当你设置了基于接口的代理时它才生效。因为注解是 不能继承 的,这就意味着如果正在使用基于类的代理时,那么事务的设置将不能被基于类的代理所识别,而且对象也将不会被事务代理所包装。

6. @Transactional 的事务开启 ,或者是基于接口的 或者是基于类的代理被创建。所以在同一个类中一个方法调用另一个方法有事务的方法,事务是不会起作用的 。

  1. public interface PersonageTempService {
  2. //删除指定id的Personage
  3. public void del(Integer Personageid) ;
  4. //删除指定id的Personage,flag
  5. public void del(Integer Personageid,boolean flag) ;
  6. }
  7. public class PersonageTempServiceBean implements PersonageTempService {
  8. private JdbcTemplate jdbcTemplate;
  9. public void del(Integer Personageid){
  10. try{
  11. this.del(Personageid,true)
  12. System.out.println("del success");
  13. }catch(Exception e){
  14. System.out.println("del failed");
  15. }
  16. }
  17. @Transactional
  18. //此时,事务根本就没有开启, 即数据库会默认提交该操作,即记录别删除掉
  19. public void del(Integer Personageid,boolean flag){
  20. if(flag == ture){
  21. jdbcTemplate.update("del from Personage where id=?", new Object[]{Personageid}, new int[]{java.sql.Types.INTEGER});
  22. throw new RuntimeException("运行期例外");
  23. }
  24. }
  25. }
  26. public class PersonageTempServiceBeanTest{
  27. PersonageTempService ps = new PersonageTempServiceBean ();
  28. ps.del(5);
  29. }
  30. }

7. Spring使用声明式事务处理,默认情况下, 如果被注解的数据库操作方法中发生了unchecked异常,所有的数据库操作将rollback ;如果发生的异常是checked异常,默认情况下数 据库操作还是会提 交的。

  1. public interface PersonageService {
  2. //删除指定id的Personage
  3. public void del(Integer Personageid) ;
  4. //获取Personage
  5. public Personage getPersonage(Integer Personageid);
  6. }
  7. //PersonageServiceBean 实现了PersonageService 接口,则基于接口的还是基于类的代理 都可以实现事务
  8. @Transactional public class PersonageServiceBean implements PersonageService {
  9. private JdbcTemplate jdbcTemplate;
  10. //发生了unchecked异常,事务回滚, @Transactional
  11. public void del(Integer Personageid){
  12. jdbcTemplate.update("del from Personage where id=?", new Object[]{Personageid},
  13. new int[]{java.sql.Types.INTEGER});
  14. throw new RuntimeException("运行期例外");
  15. }
  16. }
  1. public interface PersonageService {
  2. //删除指定id的Personage
  3. public void delete(Integer Personageid) throws Exception;
  4. //获取Personage
  5. public Personage getPersonage(Integer Personageid);
  6. }
  7. @Transactional
  8. public class PersonageServiceBean implements PersonageService {
  9. //发生了checked异常,事务不回滚,即数据库记录仍能被删除,
  10. //checked的例外,需要我们在外部用try/catch语法对调用该方法的地方进行包含 @Transactional
  11. public void delete(Integer Personageid) throws Exception{
  12. jdbcTemplate.update("delete from Personage where id=?", new Object[]{Personageid},
  13. new int[]{java.sql.Types.INTEGER});
  14. throw new Exception("运行期例外");
  15. }
  16. }

 但是,对于checked这种例外,默认情况下它是不会进行事务回滚的,但是 如果我们需要它进行事务回滚,这时候可以在delete方法上通过@Transaction这个注解来修改它的行为。

  1. @Transactional
  2. public class PersonServiceBean implements PersonService {
  3. @Transactional(rollbackFor=Exception.class)
  4. //rollbackFor这属性指定了,既使你出现了checked这种例外,那么它也会对事务进行回滚
  5. public void delete(Integer personid) throws Exception{
  6. jdbcTemplate.update("delete from person where id=?", new Object[]{personid},
  7. new int[]{java.sql.Types.INTEGER});
  8. throw new Exception("运行期例外");
  9. }
  10. }

在PersonServiceBean这个业务bean里面,有一些事务是不需要事务管理的,好比说获取数据的getPersons方法,getPerson方法。因为@Transactional 放在了类的上面。

此时,可 以采用propagation这个事务属性 @Transactional(propagation=Propagation.NOT_SUPPORTED),propagation这个属性指定了 事务传播行为,我们可以指定它不支持事务,当我们这么写了之后,Spring容器在getPersons方法执行前就不会开启事务 .

    1. @Transactional
    2. public class PersonServiceBean implements PersonService {
    3. @Transactional(propagation=Propagation.NOT_SUPPORTED)
    4. //则此方法 就不会开启事务了
    5. public Person getPerson(Integer personid)
    6. {
    7. }
    8. }

@Transactional spring 事务失效(转载)的更多相关文章

  1. @Transactional spring 事务(转载)

    原文链接: http://www.cnblogs.com/sweetchildomine/p/6978037.html?utm_source=itdadao&utm_medium=referr ...

  2. Spring事务失效的原因

    http://blog.csdn.net/paincupid/article/details/51822599 Spring事务失效的原因 5种大的原因 如使用mysql且引擎是MyISAM,则事务会 ...

  3. Spring事务失效的2种情况

    使用默认的事务处理方式 因为在java的设计中,它认为不继承RuntimeException的异常是”checkException”或普通异常,如IOException,这些异常在java语法中是要求 ...

  4. java面试记录二:spring加载流程、springmvc请求流程、spring事务失效、synchronized和volatile、JMM和JVM模型、二分查找的实现、垃圾收集器、控制台顺序打印ABC的三种线程实现

    注:部分答案引用网络文章 简答题 1.Spring项目启动后的加载流程 (1)使用spring框架的web项目,在tomcat下,是根据web.xml来启动的.web.xml中负责配置启动spring ...

  5. spring事务失效情况分析

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt113 <!--[if !supportLists]-->一.&l ...

  6. @Transactional spring事务无效的解决方案

    关于@Transactional注解 一般都认为要注意以下三点 1 .在需要事务管理的地方加@Transactional 注解.@Transactional 注解可以被应用于接口定义和接口方法.类定义 ...

  7. Spring事务失效的 8 大原因,这次可以吊打面试官了!

    今天再来一篇<吊打面试官>系列,这次真的要吊打了,哈哈!(看往期吊打系列请在后台回复:吊打,我会陆续更新--) 前几天栈长不是发了一篇文章,里面有一个关于事务失效的问题: 用 Spring ...

  8. Spring事务深入剖析--spring事务失效的原因

    之前我们讲的分布式事务的调用都是在一个service中的事务方法,去调用另外一个service中的业务方法, 如果在一个sevice中存在两个分布式事务方法,在一个seivice中两个事务方法相互嵌套 ...

  9. Spring 事务失效

    隔离级别 在 TransactionDefinition.java 接口中,定义了"四种"的隔离级别枚举: /** * [Spring 独有]使用后端数据库默认的隔离级别 * * ...

随机推荐

  1. FastDFS 初始

    FastDFS 详细介绍 FastDFS是一个开源的分布式文件系统,她对文件进行管理,功能包括:文件存储.文件同步.文件访问(文件上传.文件下载)等,解决了大容量存储和负载均衡的问题.特别适合以文件为 ...

  2. poj 1753、2965枚举

    1753题目链接 题目大意: 一个4乘4的棋盘,上面放满了正反两面分别为黑和白的棋子,翻转一个棋子会让这个棋子上下左右的棋子也翻转,给定一个初始状态,求使所有棋子颜色相同所需的最少翻转次数. 解题思路 ...

  3. 另一种方式实现事务码SE16里的结果集修改

    注: 这种方法不同于网上流传的在调试器里修改fcode的那种解决方案. 使用场景:我们需要直接在开发系统的事务码SE16里修改某些结果集的值,但是在SE16的工具栏里看不见修改按钮: 解决方案 使用/ ...

  4. IOS 社交分享

    #import <Social/Social.h> @interface HMViewController () @end @implementation HMViewController ...

  5. c++一些总结

    1.if和else if后面并没有要求一定要接else(即以else来结尾),可以直接if语句然后接其他语句,也可以if语句之后加else if语句再接其他语句

  6. CentOS 7.1上安装.Net Core

    官方网站给出了几条命令: sudo yum install libunwind libicu curl -sSL -o dotnet.tar.gz https://go.microsoft.com/f ...

  7. 使用Vue做评论+localStorage存储(js模块化)

    未分模块化 html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> &l ...

  8. 【洛谷P3959】[NOIP2017] 宝藏

    宝藏 题目链接 首先,打了一个prim,得了45分 #include<iostream> #include<cstring> #include<cstdio> #i ...

  9. 测试Storm的多源头锚定

    过程, Spout 发送msgid 1-10 一级Bolt, msgid1的tuple做为基本组合tuple, 其他8个和一组合, 然后发送给二级Bolt, 同时单个msgid对应的tuple都ack ...

  10. Qt基于tcp协议网络编程

    基于Qt网络编程: 基于tcp协议 c/s模式编程 所需要的类:QTcpServer QTcpSocket 利用qt基于tcp协议编写c/s模式程序: 两个类中的信号: QTcpServer : ne ...