2010-12-15 81 views
2

大家好我做了使用JSF应用程序配置,春季3.0,hybernate + JPA和XA transcation管理和mysql Atomikos公司是我的后端,这里每一件事情是工作正常但是插入操作,当异常抛出transcation应该回滚,但它没有发生!这里是一个小流量为我们的应用程序 我使用jsfmanagedbean用来调用我的servive,从我的服务类我transcation将开始事务回滚,但记录插入

TextileUIBean.java
包com.textile.web; public class TextileUIBean extends BaseManagedBean implements Serializable, public insertPaymentDetails() PaymentDetails PaymentDetails = new PaymentDetails(); // values are hard coded ans only only two propereties only using PaymentDetails.setCustomerName(“Manikandan”); PaymentDetails.setAmount(1000); getTextileManager()。insertPaymentDetails(PaymentDetails); } 公共ITextileManager getTextileManager(){ textileManager =(ITextileManager)的getBean( “textileManager”); return textileManager; }}

service class 


    package com.textile.web 
     public interface ITextileManager 
     { 
     public void insertPaymentDetails(PaymentDetails PaymentDetails); 
     } 
     package com.textile.web 
     public class TextileManager implements ITextileManager 
      { 
      ITextileBusiness TextileBusiness ; 

      public void setTextileBusiness(ITextileBusiness textileBusiness) { 
      this.textileBusiness = textileBusiness; 
      } 
      void insertPaymentDetails(PaymentDetails PaymentDetails) 
      { 
       TextileBusiness.insertPaymentDetails(PaymentDetails); 


      } 

     and my business class is 


package com.textile.web 

      public interface ITextileBusiness 
      { 
       public void insertPaymentDetails(PaymentDetails PaymentDetails); 
      } 

      package com.textile.web 
      public class TextileBusiness implements ITextileBusiness 
      { 
      ITextileDao textileDao; 

      public void setTextileDao(ITextileDao textileDao) { 
      this.textileDao = textileDao; 
      } 
      void insertPaymentDetails(PaymentDetails ormPaymentTable) 
      { 

       OrmPaymentTable ormPaymentTable= OrmPaymentTable(); 
       ormPaymentTable.setCustomerName(PaymentDetails.getCustomerName()); 
      ormPaymentTable.setAmount(PaymentDetails.getAmount();); 
       textileDao.insertPaymentDetails(ormPaymentTable); 
           int a=0; 
       if(a==0) 
        throw new BusinessException("Transcation Rollback");    

      } 
      } 
     and my dao class is 


package com.textile.web 
      public interface IPaymentsDao { 
       public void insertPaymentDetails(OrmPaymentTable ormPaymentTable); 
       } 
       package com.textile.web 
       public class PaymentsDao implements IPaymentsDao 
       { 
       void insertPaymentDetails(OrmPaymentTable ormPaymentTable) 
       { 
       this.getJpaTemplate().persist(ormPaymentTable); 
        after this line the record is insertinf into table    
       }    
       } 


      my FacesConfig.xml is 


    <application> 
      <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver> 
      <locale-config> 
      <default-locale>en</default-locale> 
      <supported-locale>en</supported-locale> 
      </locale-config> 
      <message-bundle>Messages</message-bundle> 
      </application> 
      <managed-bean>   <managed-bean-name>textileUIBean</managed-bean-name>             <managed-bean-class>com.textile.web.TextileUIBean</managed-bean-class> 
    <managed-bean-scope>view</managed-bean-scope> 
</managed-bean> 

和我applicationConfig.xml文件

<beans:bean id="dataSource" 
     class="org.springframework.jndi.JndiObjectFactoryBean" > 
     <beans: property name="jndiName"> 
      <beans: value>java:comp/env/jdbc/textWeb</beans:value> 
     </beans: property> 
     <beans: property name="resourceRef"> 
      <beans:value>true</beans:value> 
     </beans: property> 
    </beans: bean> 
     <beans: bean id="jpaTemplate" class="org.springframework.orm.jpa.JpaTemplate"> 
     <beans: property name="entityManagerFactory"> 
      <beans: ref bean="entityManagerFactory" /> 
     </beans: property> 
    </beans: bean> 
    <beans: bean id="entityManagerFactory" 
     class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
     <!-- hidden by shiju because we need one datasource support its in prsistence.xml !--> 
     <beans: property name="dataSource"> 
      <beans: ref bean="dataSource" /> 
     </beans: property> 
     <beans: property name="persistenceUnitName" value="payhub" /> 
     <beans: property name="jpaVendorAdapter"> 
      <beans:bean 
       class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
       <beans: property name="generateDdl" value="false" /> 
       <beans: property name="showSql" value="true" /> 
       <beans: property name="databasePlatform" value="${database.target}" /> 
      </beans: bean> 
     </beans: property> 
     <beans: property name="persistenceXmlLocation"> 
      <beans: value>classpath:META-INF/persistence.xml</beans:value> 
     </beans: property> 
    </beans: bean> 
<beans:bean id="textileManager" 
     class=" com.textile.web.TextileManager"> 
     <beans: property name="textileBusiness" ref="textileBusiness" /> 
    </beans: bean> 
    <beans: bean id="textileBusiness" class="com.textile.web.TextileBusiness"> 
     <beans: property name="textileDao" ref="textileDao" />  
    </beans: bean> 
    <beans: bean id="textileDao" class="com.textile.web.textileDao"> 
     <beans: property name="jpaTemplate"> 
      <beans: ref bean="jpaTemplate"/> 
     </beans: property> 
    </beans: bean> 

    <aop:config> 
      <aop:pointcut id="fooServiceOperation" expression="execution(* com.textile.web.*.*(..))"/> 
      <aop:advisor advice-ref="txAdvice" pointcut-ref="fooServiceOperation"/> 
      </aop:config> 
    <tx:advice id="txAdvice" transaction-manager="transactionManager"> 
    <tx:attributes>    
      <tx:method name="*" propagation="REQUIRED"/> 
     </tx:attributes> 
    </tx:advice> 

     <beans: bean id="atomikosTransactionManager" 
     class="com.atomikos.icatch.jta.UserTransactionManager" init-method="init" 
     destroy-method="close"> 
     <beans: property name="forceShutdown" value="true" /> 
     <beans: property name="startupTransactionService" value="true" /> 
    </beans:bean> 

    <beans:bean id="atomikosUserTransaction" class="com.atomikos.icatch.jta.UserTransactionImp"> 
     <beans: property name="transactionTimeout"> 
      <beans: value>3000</beans:value> 
     </beans: property> 
    </beans:bean> 

    <beans: bean id="transactionManager" 
     class="org.springframework.transaction.jta.JtaTransactionManager"> 
     <beans: property name="transactionManager"> 
      <beans: ref bean="atomikosTransactionManager" /> 
     </beans: property> 
     <beans: property name="userTransaction"> 
      <beans: ref bean="atomikosUserTransaction"/> 
     </beans: property> 
      <beans: property name="rollbackOnCommitFailure" value="true"> 
      </beans: property> 
    </beans: bean> 

and orm.xml file is 




<entity class="OrmPaymentTable" name="OrmPaymentTable"> 
<table name="ta_payment" /> 
<attributes> 
<id name="paymentId"> 
<column name="USER_ID" /> 
<generated-value strategy="AUTO" /> 
</id> 
<basic name="customerName"> 
<column name="CUST_NAME" length="50" /> 
</basic> 
<basic name="amount"> 
<column name="AMOUNT" length="50" /> 
</basic> 
</attributes> 
</entity> 

<persistence-unit name="payhub" transaction-type="JTA"> 
     <provider>org.hibernate.ejb.HibernatePersistence</provider> 
     <jta-data-source>java:comp/env/jdbc/textWeb</jta-data-source> 
     <mapping-file>META-INF/orm.xml</mapping-file> 
     <class>com.textile.web.OrmPaymentTable</class> 
     <properties> 
      <property name="hibernate.transaction.manager_lookup_class" 
       value="com.atomikos.icatch.jta.hibernate3.TransactionManagerLookup"/> 

      <property name="hibernate.transaction.factory_class" 
       value="org.hibernate.transaction.JTATransactionFactory" /> 
</properties> 
    </persistence-unit> 
</persistence> 

和我配置META-INF/JNDI的context.xml

<Context> 
     <Transaction factory="com.atomikos.icatch.jta.UserTransactionFactory"/> 
     <Resource name="jdbc/textWeb" auth="Container" 
     driverClassName="com.mysql.jdbc.Driver" user="root" password="root" 
     type="com.mysql.jdbc.jdbc2.optional.MysqlXADataSource" factory="com.mysql.jdbc.jdbc2.optional.MysqlDataSourceFactory" 
     url="jdbc:mysql://localhost:3306/textWeb" explicitUrl="true" 
     pinGlobalTxToPhysicalConnection="true"> 
    </Resource> 
    </Context> 

web.xml 

     <resource-ref> 
    <description>PaymentsDatabase</description> 
    <res-ref-name>jdbc/textWeb</res-ref-name> 
    <res-type>javax.sql.DataSource</res-type> 
    <res-auth>Container</res-auth> 
    <res-sharing-scope>Shareable</res-sharing-scope> 
</resource-ref> 

我跟踪日志..看到我transcation日志详细

78 [main] INFO atomikos - USING core version: 3.6.4 
78 [main] INFO atomikos - USING com.atomikos.icatch.console_file_name = tm.out 
78 [main] INFO atomikos - USING com.atomikos.icatch.console_file_count = 1 
78 [main] INFO atomikos - USING com.atomikos.icatch.automatic_resource_registration = true 
78 [main] INFO atomikos - USING com.atomikos.icatch.client_demarcation = false 
78 [main] INFO atomikos - USING com.atomikos.icatch.threaded_2pc = true 
78 [main] INFO atomikos - USING com.atomikos.icatch.serial_jta_transactions = false 
78 [main] INFO atomikos - USING com.atomikos.icatch.log_base_dir = .\ 
94 [main] INFO atomikos - USING com.atomikos.icatch.console_log_level = WARN 
94 [main] INFO atomikos - USING com.atomikos.icatch.max_actives = 50 
94 [main] INFO atomikos - USING com.atomikos.icatch.checkpoint_interval = 500 
94 [main] INFO atomikos - USING com.atomikos.icatch.enable_logging = false 
94 [main] INFO atomikos - USING com.atomikos.icatch.output_dir = .\ 
94 [main] INFO atomikos - USING com.atomikos.icatch.log_base_name = tmlog 
94 [main] INFO atomikos - USING com.atomikos.icatch.console_file_limit = 0 
94 [main] INFO atomikos - USING com.atomikos.icatch.max_timeout = 300000 
94 [main] INFO atomikos - USING com.atomikos.icatch.tm_unique_name = PaymentsTransactions 
94 [main] INFO atomikos - USING java.naming.factory.initial = com.sun.jndi.rmi.registry.RegistryContextFactory 
94 [main] INFO atomikos - USING java.naming.provider.url = rmi://localhost:1099 
94 [main] INFO atomikos - USING com.atomikos.icatch.service = com.atomikos.icatch.standalone.UserTransactionServiceFactory 
94 [main] INFO atomikos - USING com.atomikos.icatch.force_shutdown_on_vm_exit = false 
94 [main] INFO atomikos - USING com.atomikos.icatch.default_jta_timeout = 10000 
INFO - JtaTransactionManager.checkUserTransactionAndTransactionManager(469) | Using JTA UserTransaction: [email protected] 
INFO - JtaTransactionManager.checkUserTransactionAndTransactionManager(480) | Using JTA TransactionManager: [email protected] 
DEBUG - NameMatchTransactionAttributeSource.addTransactionalMethod(94) | Adding transactional method [*] with attribute [PROPAGATION_REQUIRED,ISOLATION_DEFAULT] 
DEBUG - AbstractPlatformTransactionManager.getTransaction(365) | Creating new transaction with name [com.evolvus.payments.manager.IPaymentsManager.findColumnChartDisplayByGateWays]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT 
40500 [http-8080-Processor24] WARN atomikos - Attempt to create a transaction with a timeout that exceeds com.atomikos.icatch.max_timeout - truncating to: 300000 
40641 [http-8080-Processor24] INFO atomikos - THREADS: using JDK thread pooling... 
40703 [http-8080-Processor24] INFO atomikos - createCompositeTransaction (3000000): created new ROOT transaction with id PaymentsTransactions0000100688 
DEBUG - AbstractPlatformTransactionManager.handleExistingTransaction(470) | Participating in existing transaction 
DEBUG - AbstractPlatformTransactionManager.handleExistingTransaction(470) | Participating in existing transaction 
DEBUG - AbstractPlatformTransactionManager.processRollback(850) | Participating transaction failed - marking existing transaction as rollback-only 
DEBUG - JtaTransactionManager.doSetRollbackOnly(1060) | Setting JTA transaction rollback-only 
49110 [http-8080-Processor24] INFO atomikos - setRollbackOnly() called for transaction PaymentsTransactions0000100688 
DEBUG - AbstractPlatformTransactionManager.processRollback(843) | Initiating transaction rollback 
49172 [http-8080-Processor24] INFO atomikos - afterCompletion (STATUS_ROLLEDBACK) called on Synchronization: org.hibernate.transaction.CacheSynchronization 
49172 [http-8080-Processor24] INFO atomikos - afterCompletion (STATUS_ROLLEDBACK) called on Synchronization: [email protected] 
49172 [http-8080-Processor24] INFO atomikos - rollback() done of transaction PaymentsTransactions0000100688 

你能帮助我吗?

+2

听起来像是你在后台使用的MyISAM它根本不支持交易。 – 2010-12-15 08:04:07

+0

我检查了我的db.I只使用InnoDB表。其他建议? – 2010-12-16 05:07:06

回答

3

显然你的数据库插入是不是你的事务管理器的当前事务的范围内发生的事情。

几个想法:

1)也许它只是没有在你的帖子,但我没有看到你的服务类春季@Transactional注解。您的控制交易界限的策略是什么?

2)由于您使用JNDI,我们没有能看到你的数据源,但如果你使用Atomikos公司,你应该用自己的XA知道池的数据源。你是?

3)您应加大Atomikos公司正常的日志记录DEBUG,看看究竟哪些SQL命令,它正在处理。

4)Atomikos保留超出正常日志文件的事务日志。这些用于恢复和其他目的。你也应该检查这些线索。

希望这会有所帮助。

更新:

MySQL有与XA事务的一些限制,你可以在这里了解here。在你的context.xml中尝试这个配置,至少看看它是否有效。它使用Atomikos提供的XA(但不支持XA)数据源。如果这个工程,那么你可以从那里:

<Transaction factory="com.atomikos.icatch.jta.UserTransactionFactory" />

和定义注入的JNDI数据源到你的实体管理器:

<Resource name="jdbc/myDataSource" auth="Container"
factory="org.apache.naming.factory.BeanFactory"
type="com.atomikos.jdbc.nonxa.AtomikosNonXADataSourceBean"
uniqueResourceName="myMySqlDatabase" driverClassName="com.mysql.jdbc.Driver" url="......" user="....." password="...." maxPoolSize="20" reapTimeout="300" />

+0

真的感谢您的回复.. – 2010-12-22 05:23:03

+0

喜Hdave 真的感谢您的回复 1策略来控制事务边界是Spring AOP的 看到 它将处理交易界限。/ – 2010-12-22 05:24:29

+0

IM配置XA意识到池数据源中的context.xml metainf <交易工厂= “com.atomikos.icatch.jta.UserTransactionFactory”/> <资源名称= “JDBC/textWeb” AUTH = “容器” driverClassName =“com.mysql.jdbc.Driver”user =“root”password =“root” type =“com.mysql.jdbc.jdbc2.optional.MysqlXADataSource”factory =“com.mysql.jdbc.jdbc2.optional。 MysqlDataSourceFactory的” URL = “的jdbc:mysql的://本地主机:3306/textWeb” explicitUrl = “真” pinGlobalTxToPhysicalConnection = “真”> 2010-12-22 05:25:25