- 浏览: 3503294 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
wanglf1207:
EJB的确是个不错的产品,只是因为用起来有点门槛,招来太多人吐 ...
weblogic-ejb-jar.xml的元素解析 -
qwfys200:
总结的不错。
Spring Web Flow 2.0 入门 -
u011577913:
u011577913 写道也能给我发一份翻译文档? 邮件437 ...
Hazelcast 参考文档-4 -
u011577913:
也能给我发一份翻译文档?
Hazelcast 参考文档-4 -
songzj001:
DbUnit入门实战
在 Java EE 应用程序的分布式事务中使用自定义隔离级别
2006 年 11 月 20 日
如果您正在构建一个应用程序,该应用程序要求在执行用例时在全局事务中具有 自定义隔离级别,您可能已经发现这是一件困难的事,因为 Java™ Transaction API 并不提供对自定义隔离级别的支持。幸运地是,Spring 框架允许您设计在全局事务中使用自定义隔离级别的 Web 和企业应用程序,但这却不是一件容易的事。在本文中,Ricardo Olivieri 用 7 个详细的步骤演示了这一过程。
许多 Java Enterprise Edition(EE)应用程序在执行用户请求时都会访问多处资源。例如,应用程序也许需要将一条消息放到一个面向消息的中间件队列中,并在相同的事务上 下文中更新数据库行。可以通过使用应用服务器提供的 Java Transaction API(JTA)事务管理器和兼容 XA 的驱动程序连接到数据资源来实现这一任务。但应用程序的需求也许会在执行一个用例时调用全局事务中的自定义隔离级别(custom isolation level) —— JTA 事务管理器并不支持自定义隔离级别。如果正在使用 Spring 框架,出这个原因,如果为 Spring 配置文件中的全局事务指定一个自定义隔离级别,将会抛出一个异常。
本文展示了一种能够 使用 Spring 来指定全局事务中的自定义隔离级别的方法。如果您部署应用程序的应用服务器,允许在定义数据源的位置指定作为数据库访问的隔离级别值,那么该方法都是有效 的。为从本文中获益,您应该熟悉 Spring 框架并理解如何在 Spring 配置文件中定义事务代理及面向方面的 advice。在对应用服务器熟悉的前提下,也假设您熟悉 Java EE 设计模式和全局/分布式事务的概念。
软
件应用程序的需求也许做了这样的规定(这里的许多技术超出了本文讨论范围),即在执行一个给定用例的过程中,必须将相同的隔离级别使用到所有的数据访问
中。需求也许还这样规定,在一个用例实现中只要访问了两项或超过两项的外部资源,该应用程序就应该使用全局事务。例如,作为用例实现的一部分,应用程序也
许会查询两个不同的数据库表并将一条消息放到消息队列中。针对这个用例的设计也许需要使用 “已提交读” 隔离级别来执行两个数据库 READ
操作。但也需要在执行不同的
用例时,应用程序会使用不同的隔离级别(如 “可重复读”)来执行这两个相同数据库的 READ
操作。在这两个用例的执行中,应用程序执行相同的数据库操作和部分相同的代码段,但却必须使用不同的隔离级别。
您可以分别为两个 READ
操作定义方法,并以要使用的隔离级别作为参数。这些方法的调用者会依据执行中的用例来指定相应的隔离级别。但即使这种方法会起作用,将这种逻辑包含在
Java 代码中并不是最佳方法,且维护代码会很困难。表面上看,利用 Spring 框架的功能似乎是更好的方法。Spring
是一个强大的框架,这在很大程度上是由于其为应用程序定义事务的强大功能。Spring
让您用一种清晰的方式指定事务属性,如隔离级别、传播行为和异常处理行为(例如,当抛出特定的异常时,事务是否应该自动回滚)。但缺乏对指定自定义隔离级
别的支持是 JTA 是一块软肋,如下列场景所说明的那样。
|
使用 JTA 事务管理器的新手或只对它了解一点的开发人员也许想要为服务对象(如 OrderService
)(参见 什么是服务对象?
)的实现定义(在 Spring 配置文件中)一个事务代理,如清单 1 所示:
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> <constructor-arg> <ref local="jtaTransactionManager" /> </constructor-arg> </bean> <bean id="orderService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager"> <ref local="transactionManager" /> </property> <property name="proxyInterfaces"> <list> <value>sample.services.OrderService</value> </list> </property> <property name="target"> <ref local="orderServiceTarget" /> </property> <property name="transactionAttributes"> <props> <prop key="save*">PROPAGATION_REQUIRED, ISOLATION_SERIALIZABLE</prop> <prop key="delete*">PROPAGATION_REQUIRED, ISOLATION_READ_UNCOMMITTED</prop> <prop key="find*">PROPAGATION_REQUIRED, ISOLATION_READ_UNCOMMITTED, readOnly</prop> </props> </property> </bean> |
清单 1 中定义了两个 bean。第一个 bean 的定义指定了应用程序将使用的事务管理器。正如您能看到的那样,这个 bean 依赖于另一个叫做 jtaTransactionManager
的 bean,而这个 bean 的定义依赖于您正在使用的应用服务器。例如,对于 IBM WebSphere Application Server 来说,这个 bean 的定义是这样的:
<bean id="jtaTransactionManager" class="org.springframework.transaction.jta.WebSphereTransactionManagerFactoryBean" singleton="true" /> |
|
清单 1
中第二个 bean(称为 orderService
)包含一个服务对象的事务代理定义,该服务对象实现了一个名为 OrderService
的接口。这个代理为三个方法声明了三个事务性定义:save()
、delete()
和 find()
。由于 “序列化” 和 “未提交读” 被指定为这些方法的隔离级别,那么期望这些就是在运行时获得的隔离级别是符合逻辑的。然而,请注意该代理定义包含了对 JTA 事务管理器的引用。如果用这个配置运行应用程序,您也许会十分惊诧。只要执行了 OrderService
实现的 save()
、delete()
或 find()
方法,就会出现这样一个异常:
org.springframework.transaction.InvalidIsolationLevelException: JtaTransactionManager does not support custom isolation levels at org.springframework.transaction.jta.JtaTransactionManager.applyIsolationLevel( JtaTransactionManager.java:617) at org.springframework.transaction.jta.JtaTransactionManager.doJtaBegin( JtaTransactionManager.java:595) at org.springframework.transaction.jta.JtaTransactionManager.doBegin( JtaTransactionManager.java:559) at org.springframework.transaction.support.AbstractPlatformTransactionManager. getTransaction(AbstractPlatformTransactionManager.java:234) ... |
出现这个错误是因为 JTA 事务管理器不支持自定义隔离级别。当使用 JTA 事务管理器时,事务代理的 bean 定义会和清单 2 中的类似:
<bean id="orderService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager"> <ref local="transactionManager" /> </property> <property name="proxyInterfaces"> <list> <value>sample.services.OrderService</value> </list> </property> <property name="target"> <ref local="orderServiceTarget" /> </property> <property name="transactionAttributes"> <props> <prop key="save*">PROPAGATION_REQUIRED, ISOLATION_DEFAULT</prop> <prop key="delete*">PROPAGATION_REQUIRED, ISOLATION_DEFAULT</prop> <prop key="find*">PROPAGATION_REQUIRED, ISOLATION_DEFAULT,readOnly </prop> </props> </property> </bean> |
请注意,和 清单 1
惟一的区别是,现在所有的隔离级别都被设置为 ISOLATION_DEFAULT
。如果要用 清单 2
中的事务配置执行一个应用程序,该代码会顺利运行。然而,您很可能想知道当执行 save()
、delete()
或 find()
方法时,使用哪个隔离级别。这个问题的答案取决于 “其依赖项”。隔离级别依赖于用于与数据库通信的数据源。
图 1 中的序列图说明了在执行 save()
方法时,OrderService
实现对象和两个数据访问对象(DAO)的交互。(正如从您的经验中得出的那样,DAO 主要用于将业务逻辑从存储访问/持久性代码中分离出来。)
图 1. OrderService
实现的 save()
方法的序列图
从 这里 看全图。
在执行 OrderService
实现的 save()
方法时使用的隔离级别由在 OrderDAO
和 CustomerDAO
数据访问对象中引用的数据源所声明。例如,如果 OrderDAO
被配置为从定义为具有 “未提交读” 隔离级别的数据源中获取连接,而 CustomerDAO
被配置为使用定义为具有 “序列化” 隔离级别的数据源,然后在通过 OrderDAO
对象访问数据时, save()
方法会使用 “未提交读” 隔离级别,而在通过 CustomerDAO
访问数据时,使用 “序列化” 隔离级别。但如果再回过头来看 清单 1
,就会发现这并不是预期的目的。相反,在一个用例执行中,单个的隔离级别将被用于所有的数据访问(如 save()
、delete()
或 find()
方法),即使不同的用例执行相同的数据库操作,并且对数据访问对象执行相同的调用集。继续读下去,看看如何实现这一目标。
|
|
|
该解决方案是一个由 7 个步骤组成的过程,在此过程中利用了名为 JdbcOperations
的 Spring 接口,该接口可以在 org.springframework.jdbc.core
包中找到。正如 Spring 文档中所描述的那样,该接口能被轻易地模拟或保存。第一步是要创建一个名为 JdbcOperationsImpl
的类,该类实现 JdbcOperations
接口。该类也实现 ApplicationContextAware
接口。
JdbcOperations
接口需要许多数据库访问操作的实现。当然,您不应该(也不应该想要)编写如此低层的代码。相反,此类的目的仅仅是作为一个代理,该代理将所有的数据访问调用转发至一个 org.springframework.jdbc.core.JdbcTemplate
实例。
您也许会回想起之前用 Spring 编写数据访问代码的经历,可以轻易地通过将一个 javax.sql.DataSource
实例传给 JdbcTemplate
的构造函数将其实例化。请记住,本文假设您正在使用一个应用服务器,该服务器将数据源定义作为隔离级别值的占位符。为在执行用例时使用相同的隔离级别,必须在执行该用例时,使用相同的 JdbcTemplate
实例来跨越所有的数据访问对象。换言之,依赖于执行中的用例,数据访问对象需要获得对 JdbcTemplate
实例的引用,该实例与(通过其 DataSource
对象)相应的隔离级别值相关联。
ApplicationContextAware
接口需要 setApplicationContext()
方法的一个实现,该方法将实现类的访问提供给 Spring 应用程序的上下文。正如稍后将会看到的那样,访问 Spring 的上下文是必需的,因为 JdbcOperationsImpl
使用它来获取 bean(通过其 ID)。JdbcOperationsImpl
类的 bean 定义如清单 3 所示:
清单 3. JdbcOperationsImpl
实例的定义
<bean id="jdbcOperations" class="application.storage.JdbcOperationsImpl" singleton="true"> <constructor-arg index="0"> <!-- Reference to a JdbcTemplate instance with a "read committed" isolation level --> <ref local="rcJdbcTemplate" /> </constructor-arg> </bean> |
|
第二步是要确保所有的数据访问对象使用 JdbcOperationsImpl
类的一个实例来与数据库进行通信,而不是 JdbcTemplate
实例。这是很明显的,因为 JdbcTemplate
类实现 JdbcOperations
接口。不需要改变数据访问对象中一行代码;只需要改变 Spring 配置文件中每个数据访问对象的配置。例如,最初的 OrderDAO
数据访问对象的定义是这样的:
<bean id="orderDAO" class="sample.dao.OrderDAOImpl" singleton="true"> <property name="jdbcOperations"> <ref local="jdbcTemplate" /> </property> </bean> |
请将 OrderDAO
数据访问对象的定义改成这样:
<bean id="orderDAO" class="sample.dao.OrderDAOImpl" singleton="true"> <property name="jdbcOperations"> <ref local="jdbcOperations" /> </property> </bean> |
现在,JdbcOperationsImpl
类中的所有访问存储资源(如 batchUpdate()
或 execute()
方法)的方法都调用一个名为 getJdbcTemplate()
的方法,如清单 4 所示:
清单 4. JdbcOperationsImpl
类中 getJdbcTemplate()
方法的实现
private JdbcTemplate getJdbcTemplate() { try { return (JdbcTemplate) applicationContext.getBean("jdbcTemplate"); } catch (ClassCastException e) { logger.warn( "Using default JdbcTemplate instance.", e); return defaultJdbcTemplate; } } |
在这段代码中,getJdbcTemplate()
方法查询 Spring 应用程序的上下文以获取相应的 JdbcTemplate
实例。请注意,使用了 jdbcTemplate
的 bean id
来查询上下文。同样,请注意如果在 getJdbcTemplate()
获取 JdbcTemplate
对象时发生错误,将返回对默认 JdbcTemplate
对象的引用。defaultJdbcTemplate
对象是使用 “已提交读” 隔离级别的 JdbcOperationsImpl
类的 JdbcTemplate
实例变量。JdbcOperationsImpl
类使用这个实例变量作为后备解决方案,以防相应的 JdbcTemplate
实例不能从应用程序的上下文中获取。(当发生这种情况时,会在日记中记一个警告。)此类的构造函数期望将默认的 JdbcTemplate
实例作为一个参数,如清单 5 所示:
清单 5. JdbcOperationsImpl
类的构造函数
public JdbcOperationsImpl(JdbcTemplate defaultJdbcTemplate) { super(); this.defaultJdbcTemplate = defaultJdbcTemplate; } |
从清单 6 中可见,只要要求应用程序的上下文返回标识为 jdbcTemplate
的对象,就会调用 IsolationLevelUtil
类的 getJdbcTemplate()
方法:
<bean id="jdbcTemplate" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> <property name="targetClass"> <value>application.services.IsolationLevelUtil</value> </property> <property name="targetMethod"> <value>getJdbcTemplate</value> </property> <property name="singleton"> <value>false</value> </property> </bean> |
|
第三步是用 清单 6
显示的定义更新 Spring 配置文件,并定义 IsolationLevelUtil
类的实现,如清单 7 所示:
public class IsolationLevelUtil { private static final ThreadLocal threadJdbcTemplate = new ThreadLocal(); private IsolationLevelUtil() { super(); } public static JdbcTemplate getJdbcTemplate() { JdbcTemplate jdbcTemplate = (JdbcTemplate) threadJdbcTemplate.get(); return jdbcTemplate; } public static void setJdbcTemplate(JdbcTemplate jdbcTemplate) { threadJdbcTemplate.set(jdbcTemplate); } } |
IsolationLevelUtil
类的 getJdbcTemplate()
方法返回和当前执行线程关联在一起的 JdbcTemplate
实例。名为 threadJdbcTemplate
的本地线程变量被用于保持线程和 JdbcTemplate
实例间的关联。您也许想知道为什么 JdbcOperationsImpl
类的 getJdbcTemplate()
方法没有显式地调用 IsolationLevelUtil
的 getJdbcTemplate()
方法。尽管这个方法会起作用,但更好的设计是让这两个类保持解耦。例如,如果想要实现一种不同的机制来获取和执行中的用例相应的 JdbcTemplate
实例,只需要改变 Spring 配置文件,而不是 JdbcOperationsImpl
类。
|
如果您正在思考哪个组件将相应的 JdbcTemplate
实例设置为 IsolationLevelUtil
类上的本地线程变量,您的思路是正确的。为此,这个值必须在线程执行的前期已经设置好了。否则,将返回 NULL
值。所以,第四步是编写一个负责设置名为 threadJdbcTemplate
的本地线程变量的组件。请将这个组件实现为一个名为 IsolationLevelAdvice
的面向方面的 advice,如清单 8 所示。这个 advice 在用例开始执行前即被应用。
清单 8. IsolationLevelAdvice
类的实现
public class IsolationLevelAdvice implements MethodInterceptor { private Map methodJdbcTemplateMap; private JdbcTemplate defaultJdbcTemplate; public IsolationLevelAdvice(Map methodJdbcTemplateMap, JdbcTemplate defaultJdbcTemplate) { super(); this.defaultJdbcTemplate = defaultJdbcTemplate; this.methodJdbcTemplateMap = methodJdbcTemplateMap; } public Object invoke(MethodInvocation invocation) throws Exception { boolean set = false; try { Method method = invocation.getMethod(); set = setThreadJdbcTemplate(method); Object rval = invocation.proceed(); return rval; } finally { if (set) { unsetThreadJdbcTemplate(); } } } public boolean setThreadJdbcTemplate(Method method) { boolean set = false; if (IsolationLevelUtil.getJdbcTemplate() == null) { JdbcTemplate jdbcTemplate = null; String methodName = method.getName(); Iterator methodPatterns = methodJdbcTemplateMap.keySet().iterator(); while (methodPatterns.hasNext()) { String methodPattern = (String) methodPatterns.next(); if (Pattern.matches(methodPattern, methodName)) { jdbcTemplate = (JdbcTemplate) methodJdbcTemplateMap.get(methodPattern); break; } } if (jdbcTemplate == null) { jdbcTemplate = defaultJdbcTemplate; } IsolationLevelUtil.setJdbcTemplate(jdbcTemplate); set = true; } return set; } public void unsetThreadJdbcTemplate() { IsolationLevelUtil.setJdbcTemplate(null); } } |
在该应用程序中,每个服务对象实现都需要此类的实例。
|
第五步是要在 Spring 配置文件中定义这个类的一个 bean 定义,该 bean 将和 OrderService
实现类关联起来,如清单 9 所示:
清单 9.针对 OrderService
实现的隔离 advice bean 的定义
<bean id="orderServiceIsolationAdvice" class="application.services.IsolationLevelAdvice" singleton="true"> <constructor-arg index="0"> <map> <entry key="save.*"> <ref local="rrJdbcTemplate" /> </entry> <entry key="delete.*"> <ref local="rcJdbcTemplate" /> </entry> <entry key="find.*"> <ref local="rcJdbcTemplate" /> </entry> </map> </constructor-arg> <constructor-arg index="1"> <ref local="rcJdbcTemplate" /> </constructor-arg> </bean> |
清单 9 中 bean 的定义显示了 IsolationLevelAdvice
类的实例的构造函数将一个对象映射表作为第一个参数。这个映射表使用字符串匹配模式作为定义在 OrderService
接口中方法的名称的键。这些模式中的每一个都被映射到一个 JdbcTemplate
实例中,该实例具有必须用于用例执行的隔离级别。构造函数的第二个参数指定 JdbcTemplate
实例,使用该实例是为了防止没有 JdbcTemplate
对象被映射到已经调用的方法中。如果在 清单 8
中仔细观察这个类的实现,会看到 IsolationLevelAdvice
实例将在运行时使用反射来确定要在 OrderService
实现对象上调用哪个方法。在确定了将执行的方法的名称后,该 advice 实例查询 methodJdbcTemplateMap
实例变量(methodJdbcTemplateMap
对象是对这个类的构造函数中第一个参数的引用)来确定在执行该用例时要使用哪个 JdbcTemplate
。
|
第六步是要指定 IsolationLevelAdvice
bean(被标识为 orderServiceIsolationAdvice
)和 OrderService
实现对象间的关联。清单 10 中显示的 bean 定义通过让 Spring 容器(被 IsolationLevelAdvice
实例标识为 orderServiceIsolationAdvice
)充当 OrderService
类实现的 advice 正好完成这项任务:
清单 10. 针对 OrderService
实现的 AOP 代理 bean 的定义
<bean id="orderServiceTarget" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces"> <value>application.services.OrderService</value> </property> <property name="interceptorNames"> <value>orderServiceIsolationAdvice</value> </property> <property name="target"> <ref bean="orderServiceImpl" /> </property> </bean> |
|
第七步也是最后的一步是要定义应用程序所需的 JdbcTemplate
实例。清单 11 显示了每个实例的定义。每个 JdbcTemplate
定义都有一个对不同数据源对象的引用。由于有四个隔离级别,所以需要四个数据源定义和四个 JdbcTemplate
定义。清单 11 也显示了这些数据源定义:
<!-- "Serializable" isolation level - JdbcTemplate --> <bean id="sJdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" singleton="true"> <property name="dataSource"> <ref local="sDataSource" /> </property> </bean> <!-- "Read repeatable" isolation level - JdbcTemplate --> <bean id="rrJdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" singleton="true"> <property name="dataSource"> <ref local="rrDataSource" /> </property> </bean> <!-- "Read committed" isolation level - JdbcTemplate --> <bean id="rcJdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" singleton="true"> <property name="dataSource"> <ref local="rcDataSource" /> </property> </bean> <!-- "Read uncommitted" isolation level - JdbcTemplate --> <bean id="ruJdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" singleton="true"> <property name="dataSource"> <ref local="ruDataSource" /> </property> </bean> <!-- "Serializable" isolation level - data source --> <bean id="sDataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName"> <value>java:comp/env/jdbc/s_ds</value> </property> </bean> <!-- "Repeatable read" isolation level - data source --> <bean id="rrDataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName"> <value>java:comp/env/jdbc/rr_ds</value> </property> </bean> <!-- "Read committed" isolation level - data source --> <bean id="rcDataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName"> <value>java:comp/env/jdbc/rc_ds</value> </property> </bean> <!-- "Read uncommitted" isolation level - data source --> <bean id="ruDataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName"> <value>java:comp/env/jdbc/ru_ds</value> </property> </bean> |
图 2 中的类图撷取了这些类中存在的关系,定义这些类是为了实现我所描述过的解决方案:
在 这里 查看全图。
在这个类图中显示的大多数关系并没有定义在 Java 源代码中,而是在 Spring 配置文件中。(这对 Spring 用户来说并不奇怪。)同样,如果将我探讨过的 Spring bean 的定义和该类图中的实体作比较,很容易看出,在 图 2
中被标识为 orderServiceIsolationAdvice
、rrTemplate
和 rcTemplate
的类在本质上并不是 Java 类。这三个类中的每个类都有一个 Spring bean 的定义(而不是 Java 类文件)。为在类图中传达这个信息,我使用了在 IsolationLevelAdvice
类和 orderServiceIsolationAdvice
间以及在 JdbcTemplate
类和 rrTemplate
及 rcTemplate
间的 “绑定关系”。orderServiceIsolationAdvice
、rrTemplate
和 rcTemplate
实体只不过是通过将其模板类的参数和实际值绑定起来从而实例化其相应的 “模板类” 的具体对象。
下载 这些类的完整的源代码,您需要这些类来实现我在本文中演示的解决方案。
|
|
如 果在技术需求中声明了在执行使用分布式事务的用例过程中应该使用相同的隔离级别,尽管 JTA 事务管理器不支持自定义隔离级别,但您的应用程序能够满足此项需求。本文提供了实现此目标的一种方法,即使用 Spring 的依赖项-注入功能来保持类的解耦。第一眼看去,该实现似乎有点复杂,但您会意识到它很直白且相当简单。在执行用例时的任何时刻访问数据库,它让您在一种 可配置的方式下使用相同的隔离级别。处理业务逻辑和持久性逻辑的 Java 代码并未改变。相反,使用在 Spring 配置文件中的设置,所有 “神奇的事情” 都在运行时发生。这就是该解决方案的设计中的主要优点之一:使实现应用程序业务逻辑和持久性逻辑的类从确保在执行用例过程中使用的相同隔离级别的类和组件 中解耦出来。
发表评论
-
说明SOA监管(SOA Governance)实例(收录备查)
2012-12-19 11:35 1751SOA 已经不是单纯技术问 ... -
Injecting Spring Beans into Java Servlets
2012-11-01 10:21 1936If you are working in a Java ... -
用 HttpServletResponseWrapper 实现 Etag 过滤器
2012-07-09 16:58 3759原文出处:http://blog.chenlb.com/200 ... -
Eclipse Indigo - Cannot install Android ADT Plugin
2012-02-29 01:17 3884When I try to install the And ... -
Eclipse Indigo - Cannot install Android ADT Plugin
2012-02-29 01:13 1988When I try to install the And ... -
[转]mybatis下的分页,支持所有的数据库
2011-07-21 13:21 14841大 家都知道,mybatis的自带分页方法只是逻 ... -
Java framework for text- & console-based forms?
2011-07-21 01:06 1711charva jcurses JNA , ... -
JNA(Java Native Access)学习入门
2011-07-21 01:04 22627Java Native Access 项目 在 ... -
使用IntrospectorCleanupListener 解决quartz引起的内存泄漏
2011-04-20 11:59 13365"在服务器运行过程中,Spring不停的运行的计划任 ... -
DBCP代码研读以及就数据库连接失效的解决
2011-03-31 11:03 3766问题 网上很多评论说DBCP有很多BUG,但是都没有指明是什 ... -
ContextLoaderListener
2010-12-06 15:58 8464(1) org.springframework.web.c ... -
Servlet3.0新功能: 异步处理
2010-12-06 15:22 3183J2EE 6和Glassfish 3V正式发 ... -
Servlet3.0引入的新特性
2010-12-06 15:20 3058Servlet3.0规范的新特性主要是为了3个目的: ... -
100個節點上運行群集亞馬遜EC2上Hazelcast
2010-12-03 23:59 3319本文的目的,適是给妳湮示的細節集群的100個節點。此湮示記錄, ... -
Spring Properties Reloaded
2010-12-02 14:54 4372Spring Properties Reloaded Som ... -
为spring2.5中的jpetstore增加perf4j监控
2010-09-02 13:51 2646perf4j是一款类似于log4j的性能检测工具. 它 ... -
语义网的学习资源大汇集(备忘)
2010-06-23 22:48 1734网上资源 http:/ ... -
使用 JOLAP 实现复杂分析查询
2010-06-06 13:42 1965Shashank Tiwari 在本文中对 ... -
HTML5 Canvas for Internet Explorer
2010-06-04 21:16 1857Canvascape http://www.benjoff ... -
大型网站架构演变和知识体系
2010-06-01 23:47 1970架构演变第一步:物 ...
相关推荐
在Spring框架中,事务管理是核心功能之一,它确保了数据操作的一致性和完整性。本教程将深入探讨如何在Spring中实现自定义事务管理器、编程式事务处理以及声明式事务`@Transactional`的使用。 首先,让我们了解事务...
- **@Transactional**:用于声明式事务管理,可以指定回滚策略和隔离级别。 - **@ResponseBody**:用于将控制器返回的结果转换为响应体,常用于Ajax或RESTful API的开发。 #### 2. **配置文件的配置** 虽然Spring...
Spring框架是Java应用程序开发中的一个核心工具,它提供了一个全面的编程和配置模型,促进了松散耦合、可测试和模块化的应用设计。在本压缩包"Spring框架测试.zip"中,包含的是用于进行Spring框架单元测试的重要组件...
在Spring框架中,自定义命令执行器是一种设计模式,它允许开发者通过一种抽象的方式来调用具体的方法,从而达到业务解耦的目的。这种模式通常应用于希望将业务逻辑与具体实现细节隔离开来,或者在调用实际方法时存在...
首先,Spring框架是Java企业级应用开发的核心组件,它提供了依赖注入(DI)和面向切面编程(AOP)等特性,使得应用程序的组件能够灵活地协作。在这个项目中,Spring作为整体架构的基石,负责管理各个组件的生命周期...
这篇文档"基于Spring框架的开发最佳实践.pdf"涵盖了多个与Spring相关的主题,包括使用Spring Data进行MongoDB 4.0事务处理、构建message-driven微服务、Spring Boot配置、前端集成、日志管理、WebFlux错误处理以及...
- **部署与更新**:将打包好的插件部署到框架指定的目录,框架会自动检测并加载新的或更新的插件。 4. **优点** - **可扩展性**:插件化设计使得系统能够轻松添加新功能,且不影响现有功能的稳定性。 - **可维护...
在IT领域,Spring框架是Java开发中的一个核心组件,它为构建高质量的、可维护的、松耦合的Java应用程序提供了强大的支持。本项目旨在详细解释Spring原生框架与SSM(Spring、SpringMVC、Mybatis)框架的整合过程,并...
事务的传播行为、隔离级别、回滚规则等可以在配置文件或注解中设置。这种方式降低了代码的复杂度,提高了可维护性。 **总结** SSH整合的关键在于如何优雅地将这三个框架集成在一起,让它们各自发挥优势,同时保持...
- **Spring WebSocket**:详细阐述了如何使用Spring框架实现WebSocket的功能。 #### 18. Spring项目:Batch, Integration, XD, and Boot - **Spring Batch**:Spring Batch是一个用于批量处理的框架,可以处理大量...
Spring框架是另一个核心组件,它提供依赖注入(DI)和面向切面编程(AOP)等功能,支持多种集成框架。面试中可能涉及: 1. Spring的核心模块和IoC容器:Bean的生命周期管理,配置方式(XML、注解、Java配置)。 2. ...
Spring 2.5 TestContext框架是Spring框架的一个重要组成部分,主要设计用于简化单元测试和集成测试的编写。这个框架提供了一种结构化的测试环境,它允许开发者在测试中利用Spring的依赖注入特性,以及对...
Spring框架提供了一种声明式和编程式的事务管理方式,允许开发者轻松地控制事务边界,确保事务的ACID(原子性、一致性、隔离性和持久性)属性。 1. **Spring声明式事务管理**:这是Spring中最常用的一种事务管理...
"spring中,如果想用自定义主键,则不要设置sequnce.txt"提示我们,在Spring配置Hibernate时,如果希望使用自定义的主键生成策略(例如,使用UUID或者自增字段),则不应设定sequence,因为sequence是Oracle数据库...
在"Spring第二章"中,我们将深入学习Spring框架的核心概念、主要功能以及如何在实际项目中使用它们。 首先,我们要理解什么是依赖注入。依赖注入是Spring框架的一个关键特性,它允许我们解耦组件间的依赖关系。通过...
在Spring框架中,事务管理是实现业务逻辑时不可或缺的一部分,它确保了数据的一致性和完整性。Spring提供了多种事务管理方式,其中基于注解的事务管理是近年来常用的模式,因为它简化了代码并提高了可读性。本文将...
在IT行业中,Spring框架是Java开发领域中广泛使用的开源框架,尤其在企业级应用中扮演着核心角色。本文将深入探讨如何使用Spring进行数据访问,包括其数据访问组件的使用、配置以及最佳实践。 首先,Spring框架提供...
Spring 框架是Java开发中的一个核心组件,尤其在企业级应用中广泛使用。它提供了许多特性,其中一项重要功能就是事务管理。事务管理确保了数据库操作的原子性、一致性、隔离性和持久性(ACID属性),这对于任何处理...
SpringCloud作为微服务架构的重要框架,广泛应用于现代企业的分布式系统开发中。这份笔记旨在帮助开发者理解和掌握SpringCloud的核心概念、组件以及实践方法。 在SpringCloud的学习中,首先需要了解的是SpringCloud...
根据提供的文件信息,“myeclipse for spring 8.6”主要涉及的是MyEclipse这款集成开发环境(IDE)与Spring框架结合使用的版本介绍及相关知识点。接下来将从几个方面详细阐述这些知识点。 ### 一、MyEclipse简介 ...