`
远去的渡口
  • 浏览: 473580 次
  • 性别: Icon_minigender_2
  • 来自: 上海转北京
社区版块
存档分类
最新评论

Spring注解事务没有起作用解决方案

 
阅读更多

如今接手一个项目,要解决一堆bug,其中有一个问题是,在同一个方法中修改两张表status的值 ,一张表修改了,另一张表没变,看代码里写了Spring注解事务,看样子是没有起到作用。

代码

/**
 * @author : cg
 * date :2010-3-15
 * description :时段结束时调度
 */
public class YdRecord extends AbstractMerchantTimerTask {

	/**
	 * 预订订单状态变更
	 */
	@Override
	@Transactional(readOnly = false, propagation = Propagation.REQUIRED)
	public void run(String merchantId, String merchantName, DataSource ds) {
		if(log.isDebugEnabled()) log.debug("开始跑YdRecord.." + merchantName);
		NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(ds);
		HashMap<String, Object> parMap = new HashMap<String, Object>();
		parMap.put(MERCHANT_ID, merchantId);
		List<Map<String,Object>> records = template.queryForList(GET_RECORD_SQL, parMap);
		if(records != null && records.size() != 0){
			for(int i=0;i<records.size();i++){
				Map<String,Object> record = records.get(i);
				String status = (String) record.get(STATUS);
				//若订单状态为 'normal' ,则置为'cancel';若订单状态为'arrivaled',则置为'over'
				if("normal".equals(status))
					record.put(STATUS, "cancel");
				if("arrivaled".equals(status))
					record.put(STATUS, "over");
				//1 update record
				template.update(UPDATE_RECORD, record);
				//2 update cell
				template.update(UPDATE_CELLS, record);
				//3 update full_search
				record.put("OLDSTR", "normal".equals(status)?"未到达":"已到达");
				record.put("NEWSTR", "normal".equals(status)?"取消":"已完成");
				template.update(UPDATE_FULL_SEARCH, record);
				if(log.isDebugEnabled()) log.debug("结束YdRecord.." + merchantName);
			}
		}
	}
	
	private static final String MERCHANT_ID = "MERCHANT_ID";
	private static final String STATUS = "STATUS";
	
	private final static String GET_RECORD_SQL = "" +
			"select t.record_id, " +
			"       t.status " +
			" from yd_record t " +
			" where t.merchant_id = :MERCHANT_ID " +
			"   and ( t.status = 'normal' or t.status = 'arrivaled' )  " +
			" and (select to_date(substr(t.pre_arrival_time,0,10)||a.end_time, 'yyyy-MM-DD hh24:mi:ss') "+
	        "  from yd_periods a "+
	        " where a.store_id = t.store_id "+
	        "   and a.periods_id = t.pre_period) <= to_date(to_char(sysdate+1, 'yyyy-MM-DD hh24:mi:ss'), 'yyyy-MM-DD hh24:mi:ss')";


	private final static String UPDATE_RECORD      = "update yd_record t set t.update_time = sysdate,t.status = :STATUS where t.record_id = :RECORD_ID";
	private final static String UPDATE_CELLS       = "update yd_cell_record t set t.status = :STATUS where and t.record_id = :RECORD_ID";
	private final static String UPDATE_FULL_SEARCH = "update yd_full_search t set t.info = replace(t.info,:OLDSTR,:NEWSTR) where t.record_id = :RECORD_ID";
}

 

我将String UPDATE_CELLS       里面的语句故意写错,然后启动定时,执行后发现果然是第一个update语句成功了,后面的一句没成功, 没有回滚。

 

这个类的父类是AbstractMerchantTimerTask

import java.util.Date;

import javax.sql.DataSource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.tongcard.platform.tip.sp.timer.SingleMerchantTimerTask;
import com.tongcard.platform.tip.sp.timer.TimerLogUtil;
import com.tongcard.platform.tip.timer.TimerException;
import com.tongcard.platform.tip.timer.model.TimerDefinition;
import com.tongcard.osf.datasource.DataSourceUtil;
public abstract class AbstractMerchantTimerTask implements SingleMerchantTimerTask, IMerchantTimerTask {
	
	protected static Log log = LogFactory.getLog(AbstractMerchantTimerTask.class);
	
	public void runWithLog(String timerId,String timerName, String merchantId,String merchantName,String dataSourceName, DataSource ds, TimerLogUtil timerLogUtil ){
		DataSourceUtil.setCurrentDataSourceName(dataSourceName);
		long startTime = System.currentTimeMillis();
		String result = SUCCESS;
		String errorInfo = null;
		try{
			this.merchantTaskDelegate.delegate(this,merchantId, merchantName,ds);//从这里调用的方法,该类中定义父级注解。
		}catch(Throwable e){
			errorInfo = e.getMessage();
			log.error(e.getMessage(),e);
			result = FAILED;
			throw new TimerException(errorInfo,e);
		}finally{		
			long endTime = System.currentTimeMillis();
			timerLogUtil.log(merchantId, merchantName, timerId, timerName, new Date(startTime), new Date(endTime), (endTime-startTime)/1000, result, errorInfo);
		}
	}
	public String getDefaultTimerId() {
		return this.getClass().getName();
	}
	public String getDefaultTimerName() {
		return this.getClass().getName();
	}
	
	/* (non-Javadoc)
	 * @see com.tongcard.platform.tip.sp.timer.task.IMerchantTimerTask#run(java.lang.String, java.lang.String, javax.sql.DataSource)
	 */
	abstract public void run(String merchantId,String merchantName,DataSource ds);
	private IMerchantTimerTaskTransDelegate merchantTaskDelegate = null;
	public IMerchantTimerTaskTransDelegate getMerchantTaskDelegate() {
		return merchantTaskDelegate;
	}
	public void setMerchantTaskDelegate(
			IMerchantTimerTaskTransDelegate merchantTaskDelegate) {
		this.merchantTaskDelegate = merchantTaskDelegate;
	}
	//constents
	private static final String SUCCESS = "success";
	private static final String FAILED = "failed";

 

 

 

 

 写有注解的部分的接口IMerchantTimerTaskTransDelegate 中定义:

public interface IMerchantTimerTaskTransDelegate {
	@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
	public void delegate(IMerchantTimerTask mtt, String merchantId,String merchantName,DataSource ds);

}

 

 

配置文件 :

<bean id="sqlMapClient"
		class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
		<property name="dataSource" ref="dataSourceProxy" />
		<property name="configLocation">
			<value>classpath:/timerconfig/ibatis/sqlmap-config.xml</value>
		</property>
		<property name="lobHandler" ref="lobHandler"/>
	</bean>
	
	<!-- 支持  @Transactional 标记 -->
	<tx:annotation-driven transaction-manager="txManager" proxy-target-class="true"/>
	
  	<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    	<property name="dataSource" ref="dataSourceProxy"/>
  	</bean>
<bean id="dataSourceProxy" class="com.tongcard.osf.datasource.DynamicDataSource">   
       <property name="targetDataSources">   
          <ref local="dataSourceMap" />  
       </property>   
       <property name="defaultTargetDataSource" ref="db1"/>   
    </bean> 

 今天一整天都在找是哪里的问题,哪位大神看出问题在哪里,还请多多指教,万分感激。

分享到:
评论
1 楼 尹鹏波 2013-02-03  
和lz遇到同样的问题!!纠结呀!

相关推荐

    关于SpringMyBatis纯注解事务不能提交的问题分析与解决

    本文主要针对在Spring + MyBatis环境下,或使用Spring JDBC时,Oracle事务不能正常提交的问题进行了深入分析,并提出了相应的解决方案。根据提供的部分内容,我们发现该问题与不同的数据源配置有关。具体来说,当...

    Spring延迟加载和声明式事务处理最终解决方案(修正版)

    为了解决这个问题,Spring提供了两种主要解决方案: 1. **Open Session in View Interceptor (OSIV)**:这是Spring MVC中的一个拦截器,它的作用是在整个视图渲染过程中保持Hibernate Session的开放,确保在需要的...

    详细整理Spring事务失效的具体场景及解决方案.docx

    如果使用@Service 注解注释的类没有被 Spring 容器管理,那么即使方法被@Transactional 注解修饰,事务也不会生效。例如,StudentServiceImpl 类没有被 Spring 容器管理,因此即使方法被@Transactional 注解修饰,...

    Spring2.0 事务处理

    在IT行业中,Spring框架是Java企业级应用开发的首选框架之一,尤其是在事务管理方面,它提供了强大而灵活的解决方案。Spring 2.0版本在事务处理方面做了许多改进,使得开发者能够更有效地管理应用程序的事务边界。这...

    Spring事务失效问题分析及解决方案

    Spring事务失效问题分析及解决方案 在本文中,我们将详细介绍 Spring 中的事务失效问题分析及解决方案。Spring 事务机制是基于 AOP 实现的,通过使用 @Transaction 注解来标注事务方法。然而,在实际开发中,可能会...

    springboot多数据源即分布式事务解决方案

    如果不想使用JTA,Spring还提供了一种基于编程式事务管理的解决方案,称为PROPAGATION_REQUIRED。在这种模式下,开发者需要手动调用`TransactionTemplate`或在Service方法上使用`@Transactional`注解来开启和管理...

    spring事务详解

    总之,Spring事务框架提供了一套功能强大、易于使用的事务管理解决方案,它不仅可以减少代码量,提高开发效率,还可以通过声明式配置来提升代码的可读性和可维护性。对于希望深入学习Spring事务管理的开发者而言,...

    Spring事务管理的jar包

    Spring提供了全面的事务管理解决方案,使得开发者可以方便地控制事务的边界,保证数据的一致性和完整性。本篇将深入探讨Spring事务管理的核心概念、工作原理以及如何使用`spring-tx-3.2.0.RELEASE.jar`这个jar包。 ...

    Spring自定义切面事务问题

    3. **解决方案:正确配置事务切面的顺序** - 在Spring中,事务管理器本身也可以被看作是一种切面,它负责在合适的时候开启和提交事务。因此,当有多个切面需要被应用到同一个方法上时,切面的执行顺序就显得尤为...

    springboot多数据源即分布式事务解决方案,添加对多线程的支持

    综上所述,Spring Boot通过其强大的框架能力,为开发者提供了实现多数据源操作、分布式事务管理和多线程支持的解决方案。开发者只需进行适当的配置和编码,就能在复杂的业务场景中确保数据的完整性和一致性。在实际...

    Spring 整合mybatis(注解&xml版声明式事务).pdf

    它通过提供一套完整的解决方案,帮助开发者进行分层开发,包括控制反转(IoC)、面向切面编程(AOP)等。而MyBatis是一个优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC...

    SpringBoot内部调用事务不起作用问题的解决方案

    SpringBoot 内部调用事务不起作用问题的解决方案 SpringBoot 框架中,事务机制是通过 AOP 代理来实现的,当我们在内部调用带事务的方法时,事务可能不会生效,这是因为 AOP 代理机制的原因。本文将介绍这个问题的...

    spring JDBC事务管理

    总结来说,Spring JDBC事务管理是Spring框架中不可或缺的一部分,它提供了一套完整的解决方案,让开发者可以轻松地在应用程序中控制事务,保证数据的一致性。无论是编程式的还是声明式的事务管理,都有其适用场景和...

    Spring+JOTM 分布式事务管理

    Spring框架作为一个广泛使用的Java应用程序开发框架,提供了多种支持事务管理的解决方案,其中包括集成JOTM(Java Open Transaction Manager)来处理分布式事务。本文将深入探讨Spring与JOTM结合使用的知识点,帮助...

    spring事务管理

    ### Spring事务管理详解 #### 一、事务管理基础概念 在深入探讨Spring事务管理之前,我们需要先理解什么是...无论是简单的数据操作还是复杂的业务逻辑,Spring都能够提供合适的解决方案,确保数据的一致性和安全性。

    spring基于AOP实现事务

    总结一下,Spring基于AOP实现的事务管理通过TransactionProxyFactoryBean,结合声明式事务配置,能够提供一种高效且易于维护的事务解决方案。它允许我们在不修改业务逻辑的情况下,统一管理和控制事务,提升了代码的...

    spring源码(注释+测试版)

    Spring框架是Java开发中最广泛应用的轻量级框架之一,它以IoC(Inversion of Control,控制反转)和AOP(Aspect Oriented Programming,面向切面编程)为核心,提供了全面的解决方案,包括数据访问、事务管理、Web...

    spring编程式事务实现

    总的来说,`TransactionTemplate`为Spring编程式事务提供了一种简洁、可复用的解决方案。通过它,开发者可以在不牺牲事务控制灵活性的同时,避免过多的事务管理代码侵入业务逻辑。然而,在实际应用中,应当根据项目...

Global site tag (gtag.js) - Google Analytics