我們所得到的是錯誤多戰爭耳
org.springframework.transaction.IllegalTransactionStateException發現預先綁定JDBC連接:預先綁定的JDBC Connection找到了!如果被告知管理數據源本身,HibernateTransactionManager不支持在DataSourceTransactionManager中運行。無論Hibernate還是JDBC訪問,都建議對單個DataSource上的所有事務使用單個HibernateTransactionManager。
它發生的地方是我們重寫事務管理器的地方,以便我們可以對doBegin,commit和rollback方法作出反應。然而,錯誤發生在我們稱之爲super.doBegin()的doBegin中,並且在我們的任何代碼實際運行之前。當我們想要的時候,錯誤也是高度間歇性的,並且不合作。
我在網上看到很多人認爲這通常意味着你有兩個事務管理器定義。我最初拒絕這個申請給我們,因爲我們沒有。我再次檢查。但是,速度並不快,也許我會這樣做。雖然我們的戰爭只有一個tx管理器,但是發生這種情況的應用程序......發生這種情況的唯一應用程序......在同一個EAR中是兩場戰爭。每個都有自己定義的spring上下文和它自己的txManager。他們會衝突嗎?這可能是我們麻煩的根源嗎?
更新 -
APP-config.xml中(至少部分可能有關......我離開的世俗bean定義了很多)
<bean id="dataSource" name="enoteDataSource dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="resourceRef"><value>false</value></property>
<property name="jndiName">
<value>${ds.jndi}</value>
</property>
</bean>
<bean id="sessionFactory" name="sessionFactory enoteSessionFactory" class = "org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource"><ref local="dataSource" /></property>
<property name="packagesToScan">
<list>
<value>gov.usdoj.afms.enote.model.*</value>
</list>
</property>
<bean id="txManager" name="txManager transactionManager" class="gov.usdoj.afms.umc.utils.hibernate.AfmsHibernateTransactionManager">
<property name="sessionFactory" ref="enoteSessionFactory" />
</bean>
<!-- some of the transaction are controlled in code through annotation -->
<tx:annotation-driven transaction-manager="txManager"/>
<!-- the transactional advice (what 'happens'; see the <aop:advisor/> bean below) -->
<tx:advice id="txActionAdvice" transaction-manager="txManager">
<!-- the transactional semantics... -->
<tx:attributes>
<tx:method name="deleteUser" propagation="REQUIRES_NEW" rollback-for="BOException" />
<tx:method name="*" propagation="REQUIRES_NEW" />
</tx:attributes>
</tx:advice>
<tx:advice id="txAdvice" transaction-manager="txManager">
<!-- the transactional semantics... -->
<tx:attributes>
<!-- all methods starting with 'fetch' are read-only -->
<tx:method name="fetch*" isolation="READ_UNCOMMITTED"/>
<!-- other methods use the default transaction settings (see below) -->
<tx:method name="*" rollback-for="Throwable" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:advisor
pointcut="execution(* gov.usdoj.afms.umc.services.ActionPanelService.*(..))"
advice-ref="txActionAdvice"/>
<aop:advisor
pointcut="execution(* gov.usdoj.afms.umc.services.AccountInfoService.*(..))"
advice-ref="txAdvice"/>
<aop:advisor
pointcut="execution(* gov.usdoj.afms.umc.services.PersonalInfoService.*(..))"
advice-ref="txAdvice"/>
<aop:advisor
pointcut="execution(* gov.usdoj.afms.umc.services.CreateUserService.*(..))"
advice-ref="txAdvice"/>
<aop:advisor
pointcut="execution(* gov.usdoj.afms.umc.services.UM04Service.*(..))"
advice-ref="txAdvice"/>
<aop:advisor
pointcut="execution(* gov.usdoj.afms.umc.services.LookupService.removeUsrOrgLvlAsgnT(..))"
advice-ref="txAdvice"/>
<aop:advisor
pointcut="execution(* gov.usdoj.afms.umc.services.LookupService.addOrUpdateUsrOrgLvlAsgnT(..))"
advice-ref="txAdvice"/>
<aop:advisor
pointcut="execution(* gov.usdoj.afms.umc.services.LookupService.removeAndAddUsrOrgLvlAsgnT(..))"
advice-ref="txAdvice"/>
<aop:advisor
pointcut="execution(* gov.usdoj.afms.umc.services.St60Service.*(..))"
advice-ref="txAdvice"/>
</aop:config>
<bean id="serviceTarge" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="txManager" />
<property name="target" ref="createUserService" />
<property name="transactionAttributes">
<props>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<bean id="UM04ServiceTarget" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager" ref="txManager" />
<property name="target" ref="UM04Service" />
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<bean id="umcLookups" class="gov.usdoj.afms.umc.application.lookups.UMCLookups" init-method="init" scope="singleton">
<property name="lookupDao" ref="LookupDao"/>
</bean>
<bean id="userSearchServiceBean" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>gov.usdoj.afms.umc.services.UserSearchService</value>
</property>
<property name="target">
<ref bean="userSearchServiceImpl"/>
</property>
<property name="interceptorNames">
<list>
<value>theLogger</value>
</list>
</property>
</bean>
的txManager覆蓋是有那麼我們可以爲CLIENT_INFO設置一些值,從而使我們能夠識別事務中的用戶和模塊,以便我們的審計觸發器記錄信息。第一
@Override
protected void doBegin(Object arg0, TransactionDefinition arg1)
{
super.doBegin(arg0, arg1);
if (!Db2ClientInfo.exists()) {
clearDBProperty();
} else {
setDBProperty(Db2ClientInfo.getClientUserId(), Db2ClientInfo.getClientApplicationId());
}
}
@Override
protected void doCommit(DefaultTransactionStatus status) {
super.doCommit(status);
clearDBProperty();
}
@Override
protected void doRollback(DefaultTransactionStatus status) {
super.doRollback(status);
clearDBProperty();
}
@SuppressWarnings("deprecation")
private void setDBProperty(String uId, String appName) {
Session session = getSessionFactory().getCurrentSession();
Properties props = new Properties();
props.setProperty(WSConnection.CLIENT_ID, uId);
props.setProperty(WSConnection.CLIENT_APPLICATION_NAME, appName);
try {
Connection nativeConn = new SimpleNativeJdbcExtractor().getNativeConnection(session.connection());
if (nativeConn instanceof WSConnection) {
WSConnection wconn = (WSConnection) nativeConn;
wconn.setClientInformation(props);
} else {
logger.error("Connection was NOT an instance of WSConnection so client ID and app could not be set");
}
} catch (Exception e) {
throw new RuntimeException("Cannot set DB parameters!", e);
}
}
/**
* Why clear this? Because we use a connection POOLER and we'd like to clear this info when it is checked into the pool.
*/
private void clearDBProperty() {
setDBProperty("", "");
}
你不應該重寫事務管理器,你可以手動啓動和停止事務。 – Jaiwo99
我們可以看到bean的定義,以及如何超越這個方法。你在你的應用程序中進行任何直接的JDBC調用..? – user2339071
@ Jaiwo99 - 手動啓動和停止?我們所做的只是試圖獲取一個掛鉤來通知tx何時啓動和停止,以便代碼可以自動響應並設置審計信息。我們使用註釋和aop事務觸發,所以我們使用它作爲單個代碼點來執行此標準工作。如果您有更好的建議,請解釋,因爲我不瞭解您關於手動的評論。 – user1187719