论坛首页 Java企业应用论坛

JTA不能回滚的问题!

浏览 7449 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-09-21  

现在公司项目就要开始了, 用 struts2 hibernate spring  开发,.

已经确定使用2个sql server 数据库(sql 2005).  于是使用JTA, jotm 实现分布式事务.

我按照网上搜索的方式配置, 有两个数据源, 产生两个sessionFactory, 但却发现事务无法回滚!!!

看网上说sql 2005 要实现 XA, 需要增加几步操作, 要考一个文件到Binn目录下, 然后执行一个存储过程.

我试了一下, 还是不行.

这个是我测试项目的代码,  就实现一个最简单的插入数据, 也不知道究竟是项目问题还是数据库问题, 总之就是不能回滚~~~

哪位朋友有使用过的经验, 求教! 万分感谢!

以下是spring完整配置:

java 代码
  1. <!---->"1.0" encoding="UTF-8"?>   
  2. <!---->"-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">   
  3.   
  4. <beans></beans>  
  5.   
  6.     <import resource="classpath:org/codehaus/xfire/spring/xfire.xml"/>   
  7.     "HelloBean" class="com.powerapps.webservice.HelloImpl" />   
  8.        
  9.     "jotm" class="org.springframework.transaction.jta.JotmFactoryBean"/>    
  10.     "transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">    
  11.         "userTransaction">"jotm"/>    
  12.        
  13.   
  14.     "dataSourceA" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown">      
  15.         "dataSource">      
  16.             class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">      
  17.                 "transactionManager">      
  18.                     "jotm" />      
  19.                       
  20.                 "driverName">      
  21.                     <value></value>com.microsoft.sqlserver.jdbc.SQLServerDriver      
  22.                       
  23.                 "url">      
  24.                     <value></value>jdbc:sqlserver://192.168.1.63:1433;selectMethod=cursor;DatabaseName=eHR;      
  25.                       
  26.                   
  27.               
  28.         "user">      
  29.             <value></value>mohr      
  30.               
  31.         "password">      
  32.             <value></value>javadev      
  33.               
  34.            
  35.   
  36.        
  37.     <!---->   
  38.     "sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">   
  39.        
  40.         <!---->   
  41.   
  42.         "mappingResources">   
  43.              <list></list>           
  44.                     <value></value>com/powerapps/model/base/Dictinfo.hbm.xml            
  45.                     <value></value>com/powerapps/model/base/Subdictinfo.hbm.xml   
  46.                        
  47.                
  48.            
  49.   
  50.   
  51.         "dataSource">   
  52.             "dataSourceA" />   
  53.            
  54.         "jtaTransactionManager">      
  55.             "jotm" />      
  56.               
  57.            
  58.         "hibernateProperties">   
  59.              <props></props>   
  60.                 "hibernate.dialect">org.hibernate.dialect.SQLServerDialect   
  61.                 "hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory   
  62.                 "hibernate.show_sql">true   
  63.                
  64.            
  65.        
  66.        
  67.     "dataSourceB" class="org.enhydra.jdbc.pool.StandardXAPoolDataSource" destroy-method="shutdown">      
  68.         "dataSource">      
  69.             class="org.enhydra.jdbc.standard.StandardXADataSource" destroy-method="shutdown">      
  70.                 "transactionManager">      
  71.                     "jotm" />      
  72.                       
  73.                 "driverName">      
  74.                     <value></value>com.microsoft.sqlserver.jdbc.SQLServerDriver      
  75.                       
  76.                 "url">      
  77.                     <value></value>jdbc:sqlserver://192.168.1.63:1433;selectMethod=cursor;DatabaseName=test;      
  78.                       
  79.                   
  80.               
  81.         "user">      
  82.             <value></value>mohr      
  83.               
  84.         "password">      
  85.             <value></value>javadev      
  86.               
  87.            
  88.   
  89.        
  90.     <!---->   
  91.     "sessionFactoryB" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">   
  92.        
  93.         <!---->   
  94.   
  95.         "mappingResources">   
  96.              <list></list>           
  97.                     <value></value>com/powerapps/model/base/Positioninfo.hbm.xml            
  98.                
  99.            
  100.   
  101.   
  102.         "dataSource">   
  103.             "dataSourceB" />   
  104.            
  105.         "jtaTransactionManager">      
  106.             "jotm" />      
  107.               
  108.            
  109.         "hibernateProperties">   
  110.              <props></props>   
  111.                 "hibernate.dialect">org.hibernate.dialect.SQLServerDialect   
  112.                 "hibernate.query.factory_class">org.hibernate.hql.classic.ClassicQueryTranslatorFactory   
  113.                 "hibernate.show_sql">true   
  114.                
  115.            
  116.        
  117.        
  118.        
  119.     "daoB" class="com.powerapps.dao.base.impl.DaoImplB">   
  120.         "sessionFactory">   
  121.             "sessionFactoryB" />   
  122.            
  123.        
  124.        
  125.     "txProxyTemplate" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">       
  126.         "transactionManager">     
  127.             "transactionManager"/>     
  128.                
  129.         "transactionAttributes">       
  130.              <props></props>      
  131.                 "get*">PROPAGATION_REQUIRED   
  132.                 "*">PROPAGATION_REQUIRED     
  133.                    
  134.                
  135.             
  136.          
  137.          
  138.     "dictProxy" parent="txProxyTemplate" >     
  139.         "target">       
  140.             class="com.powerapps.service.admin.base.impl.DictManagerImpl">       
  141.                 "sessionFactory">"sessionFactory" />   
  142.                 "daoB">"daoB" />               
  143.                    
  144.                
  145.        
  146.   
  147.   
  148.     "positionProxy" parent="txProxyTemplate" >     
  149.         "target">       
  150.             class="com.powerapps.service.admin.base.impl.PositionManagerImpl">       
  151.                 "sessionFactory">"sessionFactoryB" />              
  152.                    
  153.                
  154.        
  155.   
  156.     "DictAction" class="com.powerapps.action.admin.base.DictAction" singleton="false" autowire="byName">   
  157.        
  158.   
  159.     "SubDictAction" class="com.powerapps.action.admin.base.SubDictAction" singleton="false" autowire="byName">   
  160.        
  161.   
  162.   
  163.   

以下是在struts action中代码:

java 代码
  1. public String test()   
  2. {   
  3.    dictProxy.testJta();   
  4.   
  5.    return "DictSearchPage";   
  6. }   

 

以下是中间层的代码:  中间曾继承了一个 BaseManagerImpl,  而 BaseManagerImpl 又继承了  BaseDaoImpl

save方法就是 BaseDaoImpl 中实现的.  以下代码中头两条记录都插入进分别的库了, 应该是回滚才对!

java 代码
  1. public void testJta()   
  2. {   
  3.     try  
  4.     {   
  5.     Dictinfo aDictinfo = new Dictinfo();   
  6.     aDictinfo.setName("111");   
  7.         super.saveObject(aDictinfo);       
  8.                  //数据库1  继承过来 BaseDaoImpl 的sessionsessionFactory   
  9.   
  10.         Positioninfo position = new Positioninfo();   
  11.         position.setName("111");   
  12.         daoB.saveObject(position);         
  13.                  //数据库2  daoB中的sessionsessionFactory   
  14.   
  15.         Dictinfo dictinfo = new Dictinfo();   
  16.         super.saveObject(dictinfo);        
  17.                  //Name字段不能为空, 出错拉, 应该把之前的插入都回滚   
  18.     }   
  19.     catch(Exception e)   
  20.     {   
  21.         e.printStackTrace();   
  22.     }   
  23.        
  24. }   
   发表时间:2007-09-24  
关注中,希望有经验得朋友能够给个思路
0 请登录后投票
   发表时间:2007-09-24  

以下是中间层的代码:  中间曾继承了一个 BaseManagerImpl,  而 BaseManagerImpl 又继承了  BaseDaoImpl

save方法就是 BaseDaoImpl 中实现的.  以下代码中头两条记录都插入进分别的库了, 应该是回滚才对!

java 代码
 
  1. public void testJta()   
  2. {   
  3.     try  
  4.     {   
  5.     Dictinfo aDictinfo = new Dictinfo();   
  6.     aDictinfo.setName("111");   
  7.         super.saveObject(aDictinfo);       
  8.                  //数据库1  继承过来 BaseDaoImpl 的sessionsessionFactory   
  9.   
  10.         Positioninfo position = new Positioninfo();   
  11.         position.setName("111");   
  12.         daoB.saveObject(position);         
  13.                  //数据库2  daoB中的sessionsessionFactory   
  14.   
  15.         Dictinfo dictinfo = new Dictinfo();   
  16.         super.saveObject(dictinfo);        
  17.                  //Name字段不能为空, 出错拉, 应该把之前的插入都回滚   
  18.     }   
  19.     catch(Exception e)   
  20.     {   
  21.         e.printStackTrace();   
  22.     }   
  23.        
  24. }   


这个testJta方法配了事务了么?
0 请登录后投票
   发表时间:2007-09-24  
多谢上面两位关注!
回 daquan198163:

配事务了, testJta方法是 dictProxy 中的方法.

<bean id="txProxyTemplate" abstract="true" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">   
    <property name="transactionManager"> 
        <ref bean="transactionManager"/> 
    </property>   
    <property name="transactionAttributes">   
        <props> 
<prop key="get*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED</prop> 
        </props>   
    </property>   
</bean>  
 
 

<bean id="dictProxy" parent="txProxyTemplate" > 
    <property name="target">   
        <bean class="com.powerapps.service.admin.base.impl.DictManagerImpl">   
<property name="sessionFactory"><ref bean="sessionFactory" /></property>
<property name="daoB"><ref bean="daoB" /></property>        
</bean>   
    </property>   
</bean>
0 请登录后投票
   发表时间:2007-09-24  
问题出在这里:
# catch(Exception e)  
#     {  
#         e.printStackTrace();  
#     }
建议补习一下Spring基础
0 请登录后投票
   发表时间:2007-09-24  
to daquan198163:
不明白你的意思, 我这个异常捕捉纯粹是为了在控制台看异常情况, 没有其他任何作用的. (我这个只是测试项目, 只是为了测试分布事务)
0 请登录后投票
   发表时间:2007-09-24  
不抛异常spring不会回滚事务的
0 请登录后投票
   发表时间:2007-09-24  
谢谢 daquan198163 回答, 我testJta把代码改为:

    catch(Exception e)
    {
    throw new RuntimeException();
    }

仍然不行啊... 

顺便说句, 我以前单数据源作的时候都没有抛异常的, 却回滚了...
抛不抛异常是必要条件吗?
0 请登录后投票
   发表时间:2007-09-24  
如果这样还不行,只能怀疑SqlServer的问题了

抛异常是必要条件
0 请登录后投票
   发表时间:2007-09-26  
首先非常感谢daquan198163的回答, 终于可以回滚了, 但是在oracle10g下, sql2005下仍然不行. (正在处理中...有经验的朋友请指教啊!!!)
看来程序没有问题, 是数据库没有配好的原因(sql对j2ee支持真是垃圾, oracle什么都不用配).

现在还有几个问题:

1 我的程序没有抛异常(throw new RuntimeException()),但确实是回滚了. 这点和文档与书上说的有点出入, 不知是怎么回事? (以前作单数据源时根本没有在意这件事, 测试一下可以回滚就没有理了) 不过这个是小问题!

2 这个是关于Session的使用.
记得robbin曾经总结说: 使用JTA时是先启动事务, 在这个全局事务范围内会启动多个session, 而hibernate则先打开session再启动事务, 顺序正好相反.
我试了试OpenSessionInView模式, 可以正常使用.
这样是不是说像
Session session = getSession()
session.方法(...)

这样的代码就只能用于读数据,写数据就有问题了? 目前还没试过.

3 我问了一个朋友, 他有很多年经验了. 说JTA事务是比较占资源的, 并且jotm的bug比较多, 使用它们的话不合算, 干脆就不用分布事务. 我想请教一下各位大牛关于这些的看法.
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics