首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > Java Web开发 >

SSH事务不能回滚有关问题,求好人解答

2013-03-13 
SSH事务不能回滚问题,求好人解答本帖最后由 yuandaobo 于 2013-03-11 09:22:01 编辑项目结构大致分为三层。

SSH事务不能回滚问题,求好人解答
本帖最后由 yuandaobo 于 2013-03-11 09:22:01 编辑 项目结构大致分为三层。数据库访问层dao、业务处理层biz、action层
现在我将事务配置加在了biz层,当biz层里面有两个数据库操作时,其中一个会出错(故意让其出错的),但是第一个数据库操作还是成功了,没有回滚,不知道是什么原因。下面是sping里面的事务配置:


<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="configLocation"
value="classpath:hibernate.cfg.xml">
</property>
</bean>

<!-- 配置事务管理器 -->      
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">    
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>    
        
 <!-- 配置事务特性 ,配置add、delete和update开始的方法,事务传播特性为required -->           
    <tx:advice id="txAdvice" transaction-manager="transactionManager">    
        <tx:attributes> 
            <tx:method name="update*" propagation="REQUIRED"/>  
            <tx:method name="add*" propagation="REQUIRED"/>
            <tx:method name="del*" propagation="REQUIRED"/>
            <tx:method name="*" propagation="REQUIRED" read-only="true"/>    
        </tx:attributes>    
    </tx:advice>   
        
    <!-- 配置那些类的方法进行事务管理,当前com.ilb.dao包中的子包、类中所有方法需要,还需要参考tx:advice的设置 -->    
    <aop:config>    
        <aop:pointcut id="allManagerMethod" expression="execution (* com.cloudsoar3c.biz.impl.*.*(..))"/>    
        <aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod"/>
    </aop:config>  
    
    <tx:annotation-driven proxy-target-class="true" transaction-manager="transactionManager" />

好人路过帮看看,谢谢
下面是部分代码:
DAO层代码:

public void add(Object ogj) throws Exception{
super.getHibernateTemplate().getSessionFactory().getCurrentSession().save(ogj);
}

biz层代码:
public TOrder addNewOrder(Integer buyCount, TClient client)throws Exception{
TServerHostLicense serverHostLicense = new TServerHostLicense();
serverHostLicense.setHostId(System.currentTimeMillis()+"");
serverHostLicense.setAddTime(new Date());
serverHostLicense.setHostName("测试主机名");
serverHostLicense.setLicenseFile("licenseFile........");
serverHostLicense.setStatus(-1);
serverHostLicense.setSupportClientCount(buyCount);
serverHostLicense.setTClient(client);
//添加主机服务器信息
//boolean addResult = this.serverHostLicenseDao.add(serverHostLicense);
this.serverHostLicenseDao.add(serverHostLicense);


TLicensePrice licensePrice = getPriceByBuyCount(buyCount);//获取单价
TOrder order = new TOrder();
//生成订单ID
String orderId = this.utilBiz.getUUID(Attribute.UUID_ORDER);
order.setOrderId("1362726845687907");//此处ID故意重复,让其出错
order.setBuyCount(buyCount);
order.setOrderTime(new Date());
order.setPreferentialPrice(0);//默认优惠价格为0
order.setPrice(licensePrice.getPrice());
order.setStatus(Attribute.ORDER_STATE_DFK);//初始化状态为待付款状态
order.setTClient(client);
order.setTServerHostLicense(serverHostLicense);
order.setTotalPrice((Integer.parseInt(licensePrice.getPrice())*buyCount+""));
this.orderDao.addOrder(order);//添加新增订单到数据库中
return order;


Action层代码:
try {
order = this.orderBiz.addNewOrder(buyCount, client);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

现在问题是TServerHostLicense serverHostLicense对象添加成功、TOrder order添加失败

[解决办法]

try {
                order = this.orderBiz.addNewOrder(buyCount, client);
            } catch (Exception e) {
                // TODO Auto-generated catch block
//这里怎么没有实物回滚语句呢?XXX.rollback();
                e.printStackTrace();
            }



[解决办法]
你捕获了异常,所有回滚不了的,要么去掉try,要么在catch里加TransactionAspectSupport.currentTransactionStatus().setRollbackOnly ;
[解决办法]
看看前后是否是一个事物,是的话在catch里写代码会滚吧
[解决办法]
<aop:pointcut id="allManagerMethod" expression="execution (* com.cloudsoar3c.biz.*.*(..))"/>
试试改成这样行不行.
expression="execution (* com.cloudsoar3c.biz.*.*(..))"/>
第一个*代表的是返回值;第二个*表示的是biz下面的子包;第三个*表示的是方法名称;(..)表示的是方法参数.
试试看!!
[解决办法]


不知道你用的什么数据库,mysql?看下数据库是什么引擎的?如果不是innerdb,就不能自动提交事务。在
hibernate配置文件里加上<property name="connection.autocommit">false</property>
[解决办法]
默认的配置中,spring框架的事务设施代码仅仅标记运行时非检查异常来设置回滚标记,也就是说当抛RuntimeException实例或子类时。在默认的配置中,如果检查性异常被抛出是不会引起事务回滚的。
下面的代码片段说明了怎么给应用程序指定的checked异常回滚操作
<tx:advice id="txAdvice" transaction-manager="txManager">
    <tx:attributes>
<tx:method name="get*" read-only="true" rollback-for="NoProductInStockException"/>
<tx:method name="*"/>
    </tx:attributes>
</tx:advice>
同样,可以指定某种异常不用回滚
<tx:advice id="txAdvice">
    <tx:attributes>
<tx:method name="updateStock" no-rollback-for="InstrumentNotFoundException"/>
<tx:method name="*"/>
    </tx:attributes>
</tx:advice>
------解决方案--------------------


<!--配置事务  -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- 配置通知 -->
<tx:advice id="txAdvice">
<tx:attributes>
<tx:method name="find*" read-only="true"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<!-- 配置通知器 -->
<aop:config>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.svse.service.*Service.*(..))"/>
</aop:config>

[解决办法]
事物也跟数据库运行模式有关。你的代码你实在找不出问题,你可以看下是不是数据库的原因。
[解决办法]
spring事务管理默认回滚条件是runtimeexcetion,楼主想通过手动抛出异常来回滚的话,可以指定回滚条件
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" rollback-for="java.lang.Exception"/>
<tx:method name="doGet*" read-only="true"/>
</tx:attributes>
</tx:advice>
[解决办法]
按照我老大的说法,你配置语句里面tx:annotation-driven 这句话,不用,这是生命用注解吧,你删了试试..
如果你切入点没配错的话,照理说dao,service一直上抛应该是可以回滚的...我也不懂,在学..
[解决办法]
什么都配来配去很蛋疼

热点排行