原文地址: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. cobbler自动安装

    基础环境:centos7.2 本地IP地址:192.168.56.12 网络环境:桥接模式 一.安装cobbler # rpm -ivh http://mirrors.aliyun.com/epel/ ...

  2. bootstrap table 分页只显示分页不显示总页数等数据

    搜了下没找到解决方案,就用CSS来解决了. 把paginationDetailHAlign:"right",使pagination-detail的class为.pull-right ...

  3. Ubuntu不支持rpm安装软件解决方法

    Ubuntu不支持rpm安装软件解决方法 以前经常使用的是RedHat Linux,习惯使用rpm方法安装软件.最近发现Ubuntu系统居然不支持rpm方法安装软件,提示信息如下: root@root ...

  4. 【转】一看你就懂,超详细java中的ClassLoader详解

    http://blog.csdn.net/briblue/article/details/54973413 ClassLoader翻译过来就是类加载器,普通的java开发者其实用到的不多,但对于某些框 ...

  5. andorid 网络通信最简单demo

    要和后台进行通信 一开始发现接不到数据 后来发生了线程错误 在网上查到:在一些高版本中,与网络通信的操作因为要花费比较大的时间,所以应该放在单独的线程中去做. 但为什么一些网上demo没有放在单独的线 ...

  6. MongoDB 和 Mongoose 04

    一.安装 1. 相关 https://www.mongodb.org/dl/win32/ MongoDB的版本偶数版本为稳定版,奇数版本为开发版 MongoDB对于32位系统支持不佳,所以3.2版本以 ...

  7. override render 方法

    有时候需要在ASP.net  或MVC 中在页面呈现前,把要显示的内容作一个拦截,更改内容后显示. 只要重写 protected override void Render(System.Web.UI. ...

  8. 21.Shiro在springboot与vue前后端分离项目里的session管理

    1.前言 当决定前端与后端代码分开部署时,发现shiro自带的session不起作用了. 然后通过对请求head的分析,然后在网上查找一部分解决方案. 最终就是,登录成功之后,前端接收到后端传回来的s ...

  9. SQL、T-SQL与PL-SQL的区别

    SQL.T-SQL与PL-SQL的区别 SQL是Structrued Query Language的缩写,即结构化查询语言.它是负责与ANSI(美国国家标准学会)维护的数据库交互的标准.作为关系数据库 ...

  10. Lucene作为一个全文检索引擎

    Lucene作为一个全文检索引擎,其具有如下突出的优点: (1)索引文件格式独立于应用平台.Lucene定义了一套以8位字节为基础的索引文件格式,使得兼容系统或者不同平台的应用能够共享建立的索引文件. ...