原文地址: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. Oracle 11.1.0.6 导入导出bug

    实验环境: 11.1.0.6.0   对ANONYMOUSUSER_ALL表中分区进行备份 SQL> select TABLE_NAME,PARTITION_NAME,HIGH_VALUE,PA ...

  2. 西汉姆VS利物浦,铁锤『拳』出击,打回原『菱』形

    一.铁锤,还是铁桶?   铁锤帮西汉姆今晚摆出4-2-3-1对阵红军利物浦的4-3-3 ,阿勒戴斯曾在主场2-1战胜赫尔城时被球迷嘘,嫌他的足球太过丑陋『2010年的时候贝尼特斯也曾经诟病阿勒戴斯带队 ...

  3. codeforces 609E Minimum spanning tree for each edge

    E. Minimum spanning tree for each edge time limit per test 2 seconds memory limit per test 256 megab ...

  4. 如何使用react-redux

    之前学习了react,也学习了redux,那么react-redux是什么呢?实际上他是一个第三方的模块,他可以帮助我们在react之中更加方便的使用redux.首先如果想用react-redux,先 ...

  5. C++函数委托

    环境: win7_x64旗舰版.VS2015企业版 场景: C++标准库提供std::function类来将一个对象的调用操作封装在一个对象内部,然后可以委托调用,但是有一些弊端,例如下面的需求: 我 ...

  6. Let’s Encrypt 最近很火的免费SSL 使用教程

    2015年10月份,微博上偶然看到Let's Encrypt 推出了beta版,作为一个曾经被https虐出血的码农来说,这无疑是一个重磅消息.并且在全站Https的大趋势下,Let's Encryp ...

  7. Java中获取classpath路径下的资源文件

    ClassLoader 提供了两个方法用于从装载的类路径中取得资源: public URL  getResource (String name); public InputStream  getRes ...

  8. U盘空间释放

    U盘做成启动盘后,怎么释放空间,恢复到原来的容量.这里有个帖子,我觉得很方便,不用安装什么东西,简单直接. http://blog.sina.com.cn/s/blog_68f6e8a901014cv ...

  9. 菜鸟崛起 DB Chapter 3 MySQL 5.6的基本操作

    3   MySQL的基本操作 上面我们学习一如何安装数据库,那么这节我们来认识一下数据库: 我们在MySQL安装后,在data目录下会自动生成几个必须的数据库,可以使用SHOW DATABASES语句 ...

  10. Oracle四舍五入,向上取整,向下取整

    用oracle sql对数字进行操作: 取上取整.向下取整.保留N位小数.四舍五入.数字格式化 取整(向下取整): select floor(5.534) from dual; select trun ...