- 浏览: 3472755 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
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 1716SOA 已经不是单纯技术问 ... -
Injecting Spring Beans into Java Servlets
2012-11-01 10:21 1909If you are working in a Java ... -
用 HttpServletResponseWrapper 实现 Etag 过滤器
2012-07-09 16:58 3709原文出处:http://blog.chenlb.com/200 ... -
Eclipse Indigo - Cannot install Android ADT Plugin
2012-02-29 01:17 3837When I try to install the And ... -
Eclipse Indigo - Cannot install Android ADT Plugin
2012-02-29 01:13 1940When I try to install the And ... -
[转]mybatis下的分页,支持所有的数据库
2011-07-21 13:21 14788大 家都知道,mybatis的自带分页方法只是逻 ... -
Java framework for text- & console-based forms?
2011-07-21 01:06 1672charva jcurses JNA , ... -
JNA(Java Native Access)学习入门
2011-07-21 01:04 22524Java Native Access 项目 在 ... -
使用IntrospectorCleanupListener 解决quartz引起的内存泄漏
2011-04-20 11:59 13289"在服务器运行过程中,Spring不停的运行的计划任 ... -
DBCP代码研读以及就数据库连接失效的解决
2011-03-31 11:03 3728问题 网上很多评论说DBCP有很多BUG,但是都没有指明是什 ... -
ContextLoaderListener
2010-12-06 15:58 8424(1) org.springframework.web.c ... -
Servlet3.0新功能: 异步处理
2010-12-06 15:22 3127J2EE 6和Glassfish 3V正式发 ... -
Servlet3.0引入的新特性
2010-12-06 15:20 3028Servlet3.0规范的新特性主要是为了3个目的: ... -
100個節點上運行群集亞馬遜EC2上Hazelcast
2010-12-03 23:59 3293本文的目的,適是给妳湮示的細節集群的100個節點。此湮示記錄, ... -
Spring Properties Reloaded
2010-12-02 14:54 4343Spring Properties Reloaded Som ... -
为spring2.5中的jpetstore增加perf4j监控
2010-09-02 13:51 2609perf4j是一款类似于log4j的性能检测工具. 它 ... -
语义网的学习资源大汇集(备忘)
2010-06-23 22:48 1692网上资源 http:/ ... -
使用 JOLAP 实现复杂分析查询
2010-06-06 13:42 1924Shashank Tiwari 在本文中对 ... -
HTML5 Canvas for Internet Explorer
2010-06-04 21:16 1830Canvascape http://www.benjoff ... -
大型网站架构演变和知识体系
2010-06-01 23:47 1913架构演变第一步:物 ...
相关推荐
1.7 使用Spring的FactoryBean创建Bean 27 1.7.1 问题 27 1.7.2 解决方案 27 1.7.3 工作原理 27 1.8 使用工厂Bean和Utility Schema定义集合 29 1.8.1 问题 29 1.8.2 解决方案 29 1.8.3 工作原理 29 ...
9.1.4 事务隔离级别 9.1.5 JDBC对事务支持 9.2 ThreadLocal基础知识 9.2.1 ThreadLocal是什么 9.2.2 ThreadLocal的接口方法 9.2.3 一个TheadLocal实例 9.2.4 与Thread同步机制的比较 9.2.5 Spring使用ThreadLocal...
1.7 使用Spring的FactoryBean创建Bean 27 1.7.1 问题 27 1.7.2 解决方案 27 1.7.3 工作原理 27 1.8 使用工厂Bean和Utility Schema定义集合 29 1.8.1 问题 29 1.8.2 解决方案 29 1.8.3 工作原理 29 ...
FactoryBean 接口为使用 Spring 框架构建的应用程序添加了一个间接的级别。 IOC 示例 理解控制反转最简单的方式就是看它的实际应用。在对由三部分组成的 Spring 系列 的第 1 部分进行总结时,我使用了一个示例,...
9.1.4 事务隔离级别 9.1.5 JDBC对事务支持 9.2 ThreadLocal基础知识 9.2.1 ThreadLocal是什么 9.2.2 ThreadLocal的接口方法 9.2.3 一个TheadLocal实例 9.2.4 与Thread同步机制的比较 9.2.5 Spring使用ThreadLocal...
需要指定的是Spring 1.2.5提供了两套Hibernate的支持包,其中Hibernate 2相关的封装类位于org.springframework.orm.hibernate2.*包中,而Hibernate 3.0的封装类位于org.springframework.orm.hibernate3.*包中,...
wint 是一个基于mvc易用的 java web框架,抛开了struts2 繁琐的配置,结合django,RoR,webx,play等框架的特点,使用约定优于配置的原则,使开发者能快速的搭建web和进行快速开发。 wint提供的主要功能有: 模板与...
这样做的动机是创建隔离的类加载器,该类加载器可以轻松地与IoC框架(如Spring)和Web应用程序集成。 整个库,包括其代码库和文档,都可以在的条款和条件下。 安装 要使用JCL ,请下载并构建JCL项目,并将jcl(-...
框架提供自定义配置源,只需实现一个接口,即可从任何地方加载配置源 支持SpringBoot的自动装配,也支持Spring的配置和非Spring的项目 提供串行和并行2种模式,提供常见常见的表达式语句 提供无级嵌套的显式子流程...
Nepxion Discovery【探索】使用指南,基于Spring Cloud Greenwich版、Finchley版和Hoxton版而 制作,对于Edgware版,使用者需要自行修改。使用指南主要涉及的功能包括: 基于Header传递的全链路灰度路由,网关为路由...
* 本项目为 Maven 项目,后端使用 Spring 4 + SpringMVC 4 + Mybatis 3.4 + aspectj 1.8 * 实现了一个 **通用mapper**,免写 SQL,可进行单表和多表关联查询,自动插入一对多/多对一对象(注解配置关联对象,结合 ...
## 自研微服务框架,借鉴springCloud全家桶的微服务设计思想 #### 支持可插拔的客户端服务端注解 #### 支持三种负载设计: 1.@OrionTarget注解定向负载 2.客户端自定义负载策略 balanceStrategy,继承统一的接口...
同时具备一定的扩展性与兼容性,因为存在自定义的服务框架,或者以后会涌现出更多的流行分布式服务框架,所以会提供一些组件适配自定义服务框架。 ## Maven依赖 ```java <groupId>com.github.cjyican</groupId> ...
采用Spring+SpringMVC+Mybatis主流开源框架,遵循MVC架构,设计轻巧,使用简单,开发人员接手与二次开发简单易懂;项目依赖的核心支持jar包,都已经完全开源. 项目完成了对阿里云、腾讯云、微信生态的快速接入与代码...
系统内部使用Spring cloud 生态圈技术进行,根据当前业务拆分商品 订单 会员等服务治理,使用eureka作为服务注册中心,使用spring config进行统一配置管理,spring cloud bus进行项目配置实时变化更新,spring boo
采用Spring+SpringMVC+Mybatis主流开源框架,遵循MVC架构,设计轻巧,使用简单,开发人员接手与二次开发简单易懂; 项目依赖的核心支持jar包,都已经完全开源. 项目完成了对阿里云、腾讯云、微信生态的快速接入与...
面试题包括以下十九部分:Java 基础、容器、多线程、反射、对象拷贝、Java Web 模块、异常、网络、设计模式、Spring/Spring MVC、Spring Boot/Spring Cloud、Hibernate、Mybatis、RabbitMQ、Kafka、Zookeeper、MySql...
使用Mybatis拦截器实现对所有SQL的拦截,修改默认的Schema,从而实现多租户数据隔离的目的。 并且支持可插拔。 9、二级缓存 采用J2Cache操作缓存,第一级缓存使用内存(Caffeine),第二级缓存使用 Redis。 由于大量的...
事务隔离性的一些基础知识 在组件之间实现事务和异步提交事务(NET2.0) 其它 在.NET访问MySql数据库时的几点经验! 自动代码生成器 关于能自定义格式的、支持多语言的、支持多数据库的代码生成器的想法 发布Oracle...
3.4.3 使用自定义转换器 159 3.4.4 绑定到Bean属性的转换器 159 3.5 使用验证器进行输入校验 161 3.5.1 输入校验概述 161 3.5.2 JSF内置校验器 162 3.5.3 校验失败后的错误消息 163 3.5.4 必填校验器 165 3.6 自定义...