- 浏览: 45918 次
- 性别:
- 来自: 深圳
最新评论
/***作者:张荣华(ahuaxuan) *2007-06-16 *转载请注明出处及作者*/
出自:http://www.iteye.com/topic/87426
简介:事务是所有企业应用系统的核心,之前人们使用ejb的时候,容器事务管理(CMT),是slsb最令人称道的地方,据说很多人使用ejb,使用slsb就是为了cmt,但是spring出现之后,格局就变了,因为程序员又多了一种选择,就是声明式事务管理,声明式事务管理是基于AOP的,及AOP是它的底层特性,本文的目的就是为了和大家探讨一下spring的声明式事务管理,从源代码来分析它的背后的思想。
这个是我昨天在解决问题是看源码得一点体验,可能说得比较大概,希望大家多多讨论,把本贴得质量提高上去,因为spring实现的事务管理这部分我相信还是有点复杂的。一个人未必能想得十分清楚,在spring的声明式事务管理中,它是如何判定一个及标记一个方法是否应该是处在事务体之中呢。
首先要理解的是spring是如何来标记一个方法是否应该处在事务体之中的。有这样一个接口TransactionDefinition,其中定义了很多常量,它还有一个子接口TransactionAttribute,其中只有一个方法rollback。
TransactionDefinition中有很多常量定义,它们分别属于两种类型,传播途径和隔离级别
代码
1. /**
2. * Support a current transaction; create a new one if none exists.
3. * Analogous to EJB transaction attribute of the same name.
4. * <p>This is typically the default setting of a transaction definition.
5. */
6. int PROPAGATION_REQUIRED = 0;
当然其中也定义了隔离级别
代码
1. /**
2. * A constant indicating that dirty reads are prevented; non-repeatable reads
3. * And phantom reads can occur. This level only prohibits a transaction
4. * From reading a row with uncommitted changes in it.
5. * @see java.sql.Connection#TRANSACTION_READ_COMMITTED
6. */
7. int ISOLATION_READ_COMMITTED = Connection.TRANSACTION_READ_COMMITTED;
同时还有两个对应的方法来得到这样的传播途径和隔离级别
代码
1. /**
2. * Return the propagation behavior.
3. * Must return one of the PROPAGATION constants.
4. * @see #PROPAGATION_REQUIRED
5. * @see org.springframework.transaction.support.TransactionSynchronizationManager#isActualTransactionActive()
6. */
7. int getPropagationBehavior();
8.
9. /**
10. * Return the isolation level.
11. * Must return one of the ISOLATION constants.
12. * <p>Only makes sense in combination with PROPAGATION_REQUIRED or
13. * PROPAGATION_REQUIRES_NEW.
14. * <p>Note that a transaction manager that does not support custom
15. * isolation levels will throw an exception when given any other level
16. * than ISOLATION_DEFAULT.
17. * @see #ISOLATION_DEFAULT
18. */
19. int getIsolationLevel();
这个接口有一个默认的实现DefaultTransactionDefinition。然后它还有子类,比如说 DefaultTransactionAttribute。Spring在判断一个方法是否需要事务体的时候其实是创建一个TransactionAttribute实现的实例.
有了上面的简单介绍就可以进入真正判断是否需要事务的地方了。这个方法在TransactionAspectSupport类里,
代码
1. /**
2. * Create a transaction if necessary.
3. * @param method method about to execute
4. * @param targetClass class the method is on
5. * @return a TransactionInfo object, whether or not a transaction was created.
6. * The hasTransaction() method on TransactionInfo can be used to tell if there
7. * was a transaction created.
8. */
9. protected TransactionInfo createTransactionIfNecessary(Method method, Class targetClass) {
10. // If the transaction attribute is null, the method is non-transactional.
11. final TransactionAttribute sourceAttr =
12. this.transactionAttributeSource.getTransactionAttribute(method, targetClass);//就是在这里判断了这个方法的事务属性
13. TransactionAttribute txAttr = sourceAttr;
14.
15. // If no name specified, apply method identification as transaction name.
16. if (txAttr != null && txAttr.getName() == null) {
17. final String name = methodIdentification(method);
18. txAttr = new DelegatingTransactionAttribute(sourceAttr) {
19. public String getName() {
20. return name;
21. }
22. };
23. }
24.
25. TransactionInfo txInfo = new TransactionInfo(txAttr, method); //TransactionInfo是TransactionAspectSupport的一个内部类,它的主要功能是记录方法和对应的事务属性
26. if (txAttr != null) {
27. // We need a transaction for this method
28. if (logger.isDebugEnabled()) {
29. logger.debug("Getting transaction for " + txInfo.joinpointIdentification());
30. }
31.
32. // The transaction manager will flag an error if an incompatible tx already exists
33. txInfo.newTransactionStatus(this.transactionManager.getTransaction(txAttr));//这个方法要仔细的看
34. }
35. else {
36. // The TransactionInfo.hasTransaction() method will return
37. // false. We created it only to preserve the integrity of
38. // the ThreadLocal stack maintained in this class.
39. if (logger.isDebugEnabled())
40. logger.debug("Don't need to create transaction for [" + methodIdentification(method) +
41. "]: this method isn't transactional");
42. }
43.
44. // We always bind the TransactionInfo to the thread, even if we didn't create
45. // a new transaction here. This guarantees that the TransactionInfo stack
46. // will be managed correctly even if no transaction was created by this aspect.
47. txInfo.bindToThread();
48. return txInfo;
49. }
TransactionInfo是TransactionAspectSupport的一个内部类,它的主要功能是记录方法和对应的事务属性,在上面这个方法的最后,这个TransactionInfo对象被保存到当前线程中。
而这个方法会在事务拦截器TransactionInterceptor中被调用,TransactionInterceptor实际上是TransactionAspectSupport的子类,看看其中的invoke方法:
代码
public Object invoke(MethodInvocation invocation) throws Throwable {
1. // Work out the target class: may be <code>null</code>.
2. // The TransactionAttributeSource should be passed the target class
3. // as well as the method, which may be from an interface
4. Class targetClass = (invocation.getThis() != null) ? invocation.getThis().getClass() : null;
5.
6. // Create transaction if necessary.
7. TransactionInfo txInfo = createTransactionIfNecessary(invocation.getMethod(), targetClass);
8.
9. Object retVal = null;
10. try {
11. // This is an around advice.
12. // Invoke the next interceptor in the chain.
13. // This will normally result in a target object being invoked.
14. retVal = invocation.proceed();
15. }
16. catch (Throwable ex) {
17. // target invocation exception
18. doCloseTransactionAfterThrowing(txInfo, ex);
19. throw ex;
20. }
21. finally {
22. doFinally(txInfo);
23. }
24. doCommitTransactionAfterReturning(txInfo);//在这里执行方法结束之后需要的操作
25. return retVal;
这个方法就如同一般的interceptor需要实现的方法一样。只不过在这个方法里判断被反射的方法是否需要事务。
发表评论
-
Spring与Struts整合3种方式实例
2009-11-04 23:35 1075Spring与Struts整合3种方式实例 Sprin ... -
解惑 spring 嵌套事务
2009-10-26 14:58 1257在所有使用 spring 的应用中, 声明式事务管理可能是使用 ... -
Spring声明式事务管理源码解读(4)
2009-10-26 14:55 1025还有一点需要说明的是,AService的方法在执行之前创建的t ... -
Spring声明式事务管理源码解读(3)
2009-10-26 14:55 760上次说到spring声明式事 ... -
Spring声明式事务管理源码解读(2)
2009-10-26 14:52 759接着我们重点再回头看一下createTransactionIf ... -
在Spring中如何使用加密外部属性文件
2009-10-19 12:40 1062在Spring的开发中, ... -
Spring 配置Spring数据源
2009-10-19 11:17 804不管通过何种持久化 ...
相关推荐
Spring源代码解析(六):Spring声明式事务处理.doc
Spring声明式事务配置管理方法
spring声明式事务实例 可复制修改使用。。。。。。。。。。
Spring框架的声明式事务管理是Java开发中的核心特性,它为高效且可靠的数据操作提供了强大支持。Spring通过@Transactional注解以及底层的AOP和代理机制实现了声明式事务。这个机制允许开发者通过简单的注解就能控制...
spring声明式事务管理异常处理的测试
Spring源代码解析(六):Spring声明式事务处理 Spring源代码解析(七):Spring AOP中对拦截器调用的实现 Spring源代码解析(八):Spring驱动Hibernate的实现 Spring源代码解析(九):Spring Acegi框架鉴权的实现 ...
spring声明式事务处理demo。myeclipse工程
Java高级编程 实验报告 spring 声明事务 实验目的 掌握spring 声明式事务管理配置 实验环境 本实验采用本实验采用的eclipse或者 Myeclpse开发工具。Spring 4.0以上 Jdk1.7以上、oracle/mysql。
示例代码 博文链接:https://awaken2012.iteye.com/blog/1728283
spring声明式事务管理+jdbc+连接池 包内为代码,下载可直接执行。 一直用s2sh,感觉hibernate不好用,所以写了一个spring声明式事务管理+jdbc+连接池。
Spring 声明式事务和Spring 编程式事务
5.2.2 基于Annotation方式的声明式事务 基于Annotation方式的声明式事务 1 在Spring容器中注册事务注解驱动; 2 在需要事务管理的类或方法上使用@Transactional注解。 ...
1.掌握Myeclipse的使用。 2.掌握spring框架和hibernate框架的使用。 3. 掌握整合spring和hibernate的持久化操作编程 4.掌握基于AOP的声明式事务编程...3.配置WEB-INF/applicationContext.xml提供基于AOP的声明式事务
spring声明式事务管理_入门
spring声明式事务管理+jdbc+连接池.zip
Spring 的事务管理是 Spring 框架中一个比较重要的知识点,该知识点本身并不复杂,只是由于其比较灵活,导致初学者很难把握。本教程从基础知识开始,详细分析了 Spring 事务管理的使用方法,为读者理清思路。
Spring的声明式事务管理是采用AOP(Aspect-Oriented Programming,面向切面编程)实现的。在编程式事务管理中,各事务处理代码实际上是相似的,这就造成了代码重复;而且编程式事务管理会造成事务管理代码和被管理的...
本代码使用H2内存数据库演示spring事务使用,包括编程式事务,声明式事务@Transactional使用,自定义事务事务注解实现自定义事务管理器
基于spring boot餐厅管理系统源码 基于spring boot餐厅管理系统源码 基于spring boot餐厅管理系统源码 基于spring boot餐厅管理系统源码 基于spring boot餐厅管理系统源码 基于spring boot餐厅管理系统源码 ...