文档章节

SpringMVC+mybatis+dubbo使用事务导致服务不正常

sowhat
 sowhat
发布于 2016/09/13 13:48
字数 2109
阅读 213
收藏 3

主要解决使用dubbo框架并添加spring事务后导致服务不能正常。原因是由于使用了事务注解后provider层产生了代理对象而获取不到dubbo的Service注解。重写dubbo注解来解决此问题

先简单说下springmvc+mybatis的搭建,直接上代码

1、spring配置

<!-- 扫描注解 -->
	<context:component-scan base-package="org.dubbo">
	</context:component-scan>
	<!-- 引入属性配置文件 -->
	<bean
		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="locations">
			<list>
				<value>classpath:config/dubbo.properties</value>
				<value>classpath:config/jdbc.properties</value>
			</list>
		</property>
	</bean>

<bean id="statFilter" class="com.alibaba.druid.filter.stat.StatFilter" lazy-init="true">
		<description>状态过滤器</description>
		<property name="logSlowSql" value="true" />
		<property name="mergeSql" value="true" />
	</bean>
	<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
		destroy-method="close" init-method="init" lazy-init="true">
		<property name="driverClassName" value="${driver}" />
		<property name="url" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
		<property name="initialSize" value="${initialSize}" />
		<property name="maxActive" value="${maxActive}" />
		<property name="minIdle" value="${minIdle}" />
		<property name="maxWait" value="${maxWait}" />
		<property name="proxyFilters">
			<list>
				<ref bean="statFilter" />
			</list>
		</property>
		<property name="filters" value="${druid.filters}" />
		<property name="connectionProperties" value="password=${jdbc.password}" />
		<property name="testWhileIdle" value="true" />
		<property name="testOnBorrow" value="false" />
		<property name="testOnReturn" value="false" />
		<property name="validationQuery" value="SELECT 'x'" />
		<property name="timeBetweenLogStatsMillis" value="60000" />
		<property name="minEvictableIdleTimeMillis" value="${minEvictableIdleTimeMillis}" />
		<property name="timeBetweenEvictionRunsMillis" value="${timeBetweenEvictionRunsMillis}" />
	</bean>

  <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<description>spring和MyBatis完美整合,不需要mybatis的配置映射文件</description>
		<property name="dataSource" ref="dataSource" />
		<!-- 自动扫描mapping.xml文件 -->
		<property name="mapperLocations" value="classpath:mapper/**/*.xml" />
	</bean>
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<description>DAO接口所在包名,Spring会自动查找其下的类</description>
		<property name="basePackage" value="org.dubbo.dao" />
		<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
	</bean>
	<!-- 事务 -->
    <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>

 2、springMVC配置,使用了fastJson支持

<!-- 自动扫描该包,使SpringMVC认为包下用了@controller注解的类是控制器 -->
	<context:component-scan base-package="org.dubbo.provider">
	<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
	</context:component-scan>
	<!-- 开启mvc注解 -->
   <mvc:annotation-driven>
        <mvc:message-converters register-defaults="true">
            <bean id="fastJsonHttpMessageConverter" class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>text/html;charset=UTF-8</value>
                        <value>application/json;charset=UTF-8</value>
                    </list>
                </property>
                <property name="features">
                    <list>
                        <value>WriteMapNullValue</value>
						<value>QuoteFieldNames</value>
						<value>WriteNullNumberAsZero</value>
						<value>WriteNullStringAsEmpty</value>
						<value>WriteDateUseDateFormat</value>
						<value>WriteNullListAsEmpty</value>
						<value>PrettyFormat</value>
                    </list>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>
	<!--跨域设置 <mvc:cors>
   	 <mvc:mapping path="/**"
        allowed-origins="*"
        allowed-methods="GET,POST"
        allowed-headers="*"
        allow-credentials="true" />
	</mvc:cors> -->
	
	<bean id="viewResolver"
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<description>视图模式配置</description>
		<property name="prefix" value="/WEB-INF/jsp/" />
		<property name="suffix" value=".jsp" />
	</bean>
	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<description>配置文件上传</description>
		<property name="defaultEncoding" value="utf-8" />
		<!-- 文件大小最大值 -->
		<property name="maxUploadSize" value="10485760000" />
		<!-- 内存中的最大值 -->
		<property name="maxInMemorySize" value="40960" />
	</bean>

3、dubbo的配置,由于dubbo的Service注解不支持事务,So重写了DubboService的注解

@Inherited //加上这个表示可继承得到,
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface DubboService {

	Class<?> interfaceClass() default void.class;
	String interfaceName() default "";
	String version() default "";
	String group() default "";
	String path() default "";
	boolean export() default false;
	String token() default "";
	boolean deprecated() default false;
	boolean dynamic() default false;
	String accesslog() default "";
	int executes() default 0;
	boolean register() default false;
	int weight() default 0;
	String document() default "";
	int delay() default 0;
	String local() default "";
	String stub() default "";
	String cluster() default "";
	String proxy() default "";
	int connections() default 0;
	int callbacks() default 0;
	String onconnect() default "";
	String ondisconnect() default "";
	String owner() default "";
	String layer() default "";
	int retries() default 0;
	String loadbalance() default "";
	boolean async() default false;
	int actives() default 0;
	boolean sent() default false;
	String mock() default "";
	String validation() default "";
	int timeout() default 0;
	String cache() default "";
	String[] filter() default {};
	String[] listener() default {};
	String[] parameters() default {};
	String application() default "";
	String module() default "";
	String provider() default "";
	String[] protocol() default {};
	String monitor() default "";
	String[] registry() default {};
}
@SuppressWarnings("serial")
public class DubboServiceBean<T> extends ServiceBean<T> {

    public DubboServiceBean() {
        super();
    }

    public DubboServiceBean(DubboService service) {
        appendAnnotation(DubboService.class, service);
    }
}

注解的bean,添加自定义注解的支持

public class AnnotationBean extends AbstractConfig
		implements DisposableBean, BeanFactoryPostProcessor, BeanPostProcessor, ApplicationContextAware {

	private String annotationPackage;

	private String[] annotationPackages;

	private final Set<ServiceConfig<?>> serviceConfigs = new ConcurrentHashSet<ServiceConfig<?>>();

	private final ConcurrentMap<String, ReferenceBean<?>> referenceConfigs = new ConcurrentHashMap<String, ReferenceBean<?>>();

	public String getPackage() {
		return annotationPackage;
	}

	public void setPackage(String annotationPackage) {
		this.annotationPackage = annotationPackage;
		this.annotationPackages = (annotationPackage == null || annotationPackage.length() == 0) ? null
				: Constants.COMMA_SPLIT_PATTERN.split(annotationPackage);
	}

	private ApplicationContext applicationContext;

	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;
	}

	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		if (annotationPackage == null || annotationPackage.length() == 0) {
			return;
		}
		if (beanFactory instanceof BeanDefinitionRegistry) {
			try {
				// init scanner
				Class<?> scannerClass = ReflectUtils
						.forName("org.springframework.context.annotation.ClassPathBeanDefinitionScanner");
				Object scanner = scannerClass
						.getConstructor(new Class<?>[] { BeanDefinitionRegistry.class, boolean.class })
						.newInstance(new Object[] { (BeanDefinitionRegistry) beanFactory, true });
				// add filter
				Class<?> filterClass = ReflectUtils
						.forName("org.springframework.core.type.filter.AnnotationTypeFilter");
				Object filter = filterClass.getConstructor(Class.class).newInstance(DubboService.class);
				Method addIncludeFilter = scannerClass.getMethod("addIncludeFilter",
						ReflectUtils.forName("org.springframework.core.type.filter.TypeFilter"));
				addIncludeFilter.invoke(scanner, filter);
				// scan packages
				String[] packages = Constants.COMMA_SPLIT_PATTERN.split(annotationPackage);
				Method scan = scannerClass.getMethod("scan", new Class<?>[] { String[].class });
				scan.invoke(scanner, new Object[] { packages });
			} catch (Throwable e) {
				// spring 2.0
			}
		}
	}

	public void destroy() throws Exception {
		for (ServiceConfig<?> serviceConfig : serviceConfigs) {
			try {
				serviceConfig.unexport();
			} catch (Throwable e) {
				logger.error(e.getMessage(), e);
			}
		}
		for (ReferenceConfig<?> referenceConfig : referenceConfigs.values()) {
			try {
				referenceConfig.destroy();
			} catch (Throwable e) {
				logger.error(e.getMessage(), e);
			}
		}
	}

	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		if (!isMatchPackage(bean)) {
			return bean;
		}
		DubboService service = bean.getClass().getAnnotation(DubboService.class);
		if (service != null) {
			DubboServiceBean<Object> serviceConfig = new DubboServiceBean<Object>(service);
			if (void.class.equals(service.interfaceClass()) && "".equals(service.interfaceName())) {
				if (bean.getClass().getInterfaces().length > 0) {
					serviceConfig.setInterface(bean.getClass().getInterfaces()[0]);
				} else {
					throw new IllegalStateException("Failed to export remote service class " + bean.getClass().getName()
							+ ", cause: The @Service undefined interfaceClass or interfaceName, and the service class unimplemented any interfaces.");
				}
			}
			if (applicationContext != null) {
				serviceConfig.setApplicationContext(applicationContext);
				if (service.registry() != null && service.registry().length > 0) {
					List<RegistryConfig> registryConfigs = new ArrayList<RegistryConfig>();
					for (String registryId : service.registry()) {
						if (registryId != null && registryId.length() > 0) {
							registryConfigs
									.add((RegistryConfig) applicationContext.getBean(registryId, RegistryConfig.class));
						}
					}
					serviceConfig.setRegistries(registryConfigs);
				}
				if (service.provider() != null && service.provider().length() > 0) {
					serviceConfig.setProvider(
							(ProviderConfig) applicationContext.getBean(service.provider(), ProviderConfig.class));
				}
				if (service.monitor() != null && service.monitor().length() > 0) {
					serviceConfig.setMonitor(
							(MonitorConfig) applicationContext.getBean(service.monitor(), MonitorConfig.class));
				}
				if (service.application() != null && service.application().length() > 0) {
					serviceConfig.setApplication((ApplicationConfig) applicationContext.getBean(service.application(),
							ApplicationConfig.class));
				}
				if (service.module() != null && service.module().length() > 0) {
					serviceConfig
							.setModule((ModuleConfig) applicationContext.getBean(service.module(), ModuleConfig.class));
				}
				if (service.provider() != null && service.provider().length() > 0) {
					serviceConfig.setProvider(
							(ProviderConfig) applicationContext.getBean(service.provider(), ProviderConfig.class));
				} else {

				}
				if (service.protocol() != null && service.protocol().length > 0) {
					List<ProtocolConfig> protocolConfigs = new ArrayList<ProtocolConfig>();
					for (String protocolId : service.registry()) {
						if (protocolId != null && protocolId.length() > 0) {
							protocolConfigs
									.add((ProtocolConfig) applicationContext.getBean(protocolId, ProtocolConfig.class));
						}
					}
					serviceConfig.setProtocols(protocolConfigs);
				}
				try {
					serviceConfig.afterPropertiesSet();
				} catch (RuntimeException e) {
					throw (RuntimeException) e;
				} catch (Exception e) {
					throw new IllegalStateException(e.getMessage(), e);
				}
			}
			serviceConfig.setRef(bean);
			serviceConfigs.add(serviceConfig);
			serviceConfig.export();
		}
		return bean;
	}

	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		if (!isMatchPackage(bean)) {
			return bean;
		}
		Method[] methods = bean.getClass().getMethods();
		for (Method method : methods) {
			String name = method.getName();
			if (name.length() > 3 && name.startsWith("set") && method.getParameterTypes().length == 1
					&& Modifier.isPublic(method.getModifiers()) && !Modifier.isStatic(method.getModifiers())) {
				try {
					DubboReference reference = method.getAnnotation(DubboReference.class);
					if (reference != null) {
						Object value = refer(reference, method.getParameterTypes()[0]);
						if (value != null) {
							method.invoke(bean, new Object[] { value });
							continue;
						}
					}
				} catch (Throwable e) {
					logger.error("Failed to init remote service reference at method " + name + " in class "
							+ bean.getClass().getName() + ", cause: " + e.getMessage(), e);
				}
				try {
					Reference reference = method.getAnnotation(Reference.class);
					if (reference != null) {
						Object value = refer(reference, method.getParameterTypes()[0]);
						if (value != null) {
							method.invoke(bean, new Object[] { value });
						}
					}
				} catch (Throwable e) {
					logger.error("Failed to init remote service reference at method " + name + " in class "
							+ bean.getClass().getName() + ", cause: " + e.getMessage(), e);
				}
			}
		}
		Field[] fields = bean.getClass().getDeclaredFields();
		for (Field field : fields) {
			try {
				if (!field.isAccessible()) {
					field.setAccessible(true);
				}
				DubboReference dubboReference = field.getAnnotation(DubboReference.class);
				if (dubboReference != null) {
					Object value = refer(dubboReference, field.getType());
					if (value != null) {
						field.set(bean, value);
						continue;
					}
				}
				Reference reference = field.getAnnotation(Reference.class);
				if (reference != null) {
					Object value = refer(reference, field.getType());
					if (value != null) {
						field.set(bean, value);
					}
				}
			} catch (Throwable e) {
				logger.error("Failed to init remote service reference at filed " + field.getName() + " in class "
						+ bean.getClass().getName() + ", cause: " + e.getMessage(), e);
			}
		}
		return bean;
	}

	private Object refer(DubboReference reference, Class<?> referenceClass) { // method.getParameterTypes()[0]
		String interfaceName;
		if (!"".equals(reference.interfaceName())) {
			interfaceName = reference.interfaceName();
		} else if (!void.class.equals(reference.interfaceClass())) {
			interfaceName = reference.interfaceClass().getName();
		} else if (referenceClass.isInterface()) {
			interfaceName = referenceClass.getName();
		} else {
			throw new IllegalStateException(
					"The @Reference undefined interfaceClass or interfaceName, and the property type "
							+ referenceClass.getName() + " is not a interface.");
		}
		String key = reference.group() + "/" + interfaceName + ":" + reference.version();
		ReferenceBean<?> referenceConfig = referenceConfigs.get(key);
		if (referenceConfig == null) {
			referenceConfig = new DubboReferenceBean<Object>(reference);
			if (void.class.equals(reference.interfaceClass()) && "".equals(reference.interfaceName())
					&& referenceClass.isInterface()) {
				referenceConfig.setInterface(referenceClass);
			}
			if (applicationContext != null) {
				referenceConfig.setApplicationContext(applicationContext);
				if (reference.registry() != null && reference.registry().length > 0) {
					List<RegistryConfig> registryConfigs = new ArrayList<RegistryConfig>();
					for (String registryId : reference.registry()) {
						if (registryId != null && registryId.length() > 0) {
							registryConfigs
									.add((RegistryConfig) applicationContext.getBean(registryId, RegistryConfig.class));
						}
					}
					referenceConfig.setRegistries(registryConfigs);
				}
				if (reference.consumer() != null && reference.consumer().length() > 0) {
					referenceConfig.setConsumer(
							(ConsumerConfig) applicationContext.getBean(reference.consumer(), ConsumerConfig.class));
				}
				if (reference.monitor() != null && reference.monitor().length() > 0) {
					referenceConfig.setMonitor(
							(MonitorConfig) applicationContext.getBean(reference.monitor(), MonitorConfig.class));
				}
				if (reference.application() != null && reference.application().length() > 0) {
					referenceConfig.setApplication((ApplicationConfig) applicationContext
							.getBean(reference.application(), ApplicationConfig.class));
				}
				if (reference.module() != null && reference.module().length() > 0) {
					referenceConfig.setModule(
							(ModuleConfig) applicationContext.getBean(reference.module(), ModuleConfig.class));
				}
				if (reference.consumer() != null && reference.consumer().length() > 0) {
					referenceConfig.setConsumer(
							(ConsumerConfig) applicationContext.getBean(reference.consumer(), ConsumerConfig.class));
				}
				try {
					referenceConfig.afterPropertiesSet();
				} catch (RuntimeException e) {
					throw (RuntimeException) e;
				} catch (Exception e) {
					throw new IllegalStateException(e.getMessage(), e);
				}
			}
			referenceConfigs.putIfAbsent(key, referenceConfig);
			referenceConfig = referenceConfigs.get(key);
		}
		return referenceConfig.get();
	}

	private Object refer(Reference reference, Class<?> referenceClass) { // method.getParameterTypes()[0]
		String interfaceName;
		if (!"".equals(reference.interfaceName())) {
			interfaceName = reference.interfaceName();
		} else if (!void.class.equals(reference.interfaceClass())) {
			interfaceName = reference.interfaceClass().getName();
		} else if (referenceClass.isInterface()) {
			interfaceName = referenceClass.getName();
		} else {
			throw new IllegalStateException(
					"The @Reference undefined interfaceClass or interfaceName, and the property type "
							+ referenceClass.getName() + " is not a interface.");
		}
		String key = reference.group() + "/" + interfaceName + ":" + reference.version();
		ReferenceBean<?> referenceConfig = referenceConfigs.get(key);
		if (referenceConfig == null) {
			referenceConfig = new ReferenceBean<Object>(reference);
			if (void.class.equals(reference.interfaceClass()) && "".equals(reference.interfaceName())
					&& referenceClass.isInterface()) {
				referenceConfig.setInterface(referenceClass);
			}
			if (applicationContext != null) {
				referenceConfig.setApplicationContext(applicationContext);
				if (reference.registry() != null && reference.registry().length > 0) {
					List<RegistryConfig> registryConfigs = new ArrayList<RegistryConfig>();
					for (String registryId : reference.registry()) {
						if (registryId != null && registryId.length() > 0) {
							registryConfigs
									.add((RegistryConfig) applicationContext.getBean(registryId, RegistryConfig.class));
						}
					}
					referenceConfig.setRegistries(registryConfigs);
				}
				if (reference.consumer() != null && reference.consumer().length() > 0) {
					referenceConfig.setConsumer(
							(ConsumerConfig) applicationContext.getBean(reference.consumer(), ConsumerConfig.class));
				}
				if (reference.monitor() != null && reference.monitor().length() > 0) {
					referenceConfig.setMonitor(
							(MonitorConfig) applicationContext.getBean(reference.monitor(), MonitorConfig.class));
				}
				if (reference.application() != null && reference.application().length() > 0) {
					referenceConfig.setApplication((ApplicationConfig) applicationContext
							.getBean(reference.application(), ApplicationConfig.class));
				}
				if (reference.module() != null && reference.module().length() > 0) {
					referenceConfig.setModule(
							(ModuleConfig) applicationContext.getBean(reference.module(), ModuleConfig.class));
				}
				if (reference.consumer() != null && reference.consumer().length() > 0) {
					referenceConfig.setConsumer(
							(ConsumerConfig) applicationContext.getBean(reference.consumer(), ConsumerConfig.class));
				}
				try {
					referenceConfig.afterPropertiesSet();
				} catch (RuntimeException e) {
					throw (RuntimeException) e;
				} catch (Exception e) {
					throw new IllegalStateException(e.getMessage(), e);
				}
			}
			referenceConfigs.putIfAbsent(key, referenceConfig);
			referenceConfig = referenceConfigs.get(key);
		}
		return referenceConfig.get();
	}

	private boolean isMatchPackage(Object bean) {
		if (annotationPackages == null || annotationPackages.length == 0) {
			return true;
		}
		String beanClassName = bean.getClass().getName();
		for (String pkg : annotationPackages) {
			if (beanClassName.startsWith(pkg)) {
				return true;
			}
		}
		return false;
	}

}

 重写dubbo的xml解析器

public class DubboNamespaceHandler extends NamespaceHandlerSupport {

    static {
        Version.checkDuplicate(DubboNamespaceHandler.class);
    }

    public void init() {
        registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));
        registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.class, true));
        registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true));
        registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));
        registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderConfig.class, true));
        registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerConfig.class, true));
        registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true));
        registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(DubboServiceBean.class, true));
        registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(DubboReferenceBean.class, false));
        registerBeanDefinitionParser("annotation", new DubboBeanDefinitionParser(AnnotationBean.class, true));
    }

}

dubbo xml配置

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee"
	xmlns:dubbo="http://code.alibabatech.com/schema/idubbo" xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
	http://www.springframework.org/schema/jee
	http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context-3.1.xsd
	http://code.alibabatech.com/schema/idubbo
	http://code.alibabatech.com/schema/idubbo/idubbo.xsd"
	default-lazy-init="false">
	<!-- 提供方应用名称信息,这个相当于起一个名字,我们dubbo管理页面比较清晰是哪个应用暴露出来的 -->
	<dubbo:application name="${dubbo.application.name}" logger="slf4j" />
	<!-- 使用zookeeper注册中心暴露服务地址 -->
	<dubbo:registry address="${dubbo.registry.address}" check="false" />
	<!-- 用dubbo协议在20880端口暴露服务 -->
	<dubbo:protocol name="dubbo" port="${dubbo.protocol.port}" threads="${dubbo.protocol.threads}" />
	<!-- 服务端要暴露的服务接口,注解@com.alibaba.dubbo.config.annotation.Service -->
	<dubbo:annotation package="org.dubbo" />
</beans>

在resources下面新建META-INF文件夹

在spring.handlers 中指定解析器为上面的类。

在provider下的接口实现类使用@DubboService注解并指定interfaceClass=接口的class,这样加了spring事务才可以正确的发布。

在consumer中使用@Reference注入对象

© 著作权归作者所有

上一篇: GitBook安装
下一篇: FDFS存储Linux安装
sowhat
粉丝 2
博文 27
码字总数 19682
作品 0
南京
程序员
私信 提问
加载中

评论(3)

sowhat
sowhat 博主

引用来自“spark2016”的评论

这个是重写了一个新的注解,那原来的Service注解是废弃了吗?
由于本身的Service注解上没有@Inherited //加上这个表示可继承得到。事务在动态代理时这个类的时候就会出现问题
s
spark2016
在AnnotationBean中,你只改了Service和ServiceBean这两个类型,还是方法也有改动?
s
spark2016
这个是重写了一个新的注解,那原来的Service注解是废弃了吗?
MyBatis的Batch处理导致秒杀系统超卖的问题

2015-08-14 周五,线上乐购做活动,1元秒杀大闸蟹,库存设置为10 ,结果卖出去15个,并且线上存在脏数据,有些关联表数据不全。 执行原理:乐购调用订单平台下单,在订单平台调用促销逻辑,在...

陶邦仁
2015/11/15
367
1
解决MySQL中死进程(一个联合查询耗时32s)

解决MySQL中死进程(一个联合查询耗时32s) 很奇怪的现象,一个联合查询(in)直接执行sql脚本的时候,Navicat Premium直接假死; 检查是否有死进程: SELECT * FROM INFORMATION_SCHEMA.INN...

xiaocao13140
2018/06/15
0
0
数据库死锁导致分布事务中大批量更新数据库不成功

未签收的订单十五天之后自动签收:总共2个步骤: step1 在乐购系统中批量更新未签收订单的状态,step2: 通过RPC修改订单系统的订单状态, step1和step2放到一个事务中。然后发现step2 订单D...

陶邦仁
2015/11/15
463
0
关于Mongo的一些坑

和大多数人一样,从Mysql转到Mongo的过程中,思维上经历了很大的转变。下面来说几点我遇到的坑: 1.单文档16M 这个是最多人碰到的,我也碰到过,当然,幸好是因为操作有误,导致这种不正常的...

大土豆8
2017/07/18
0
0
别使用嵌套事务

公司之前一直存在一个规范,就是禁止嵌套事务的使用,一直不太明白为什么,试了下应该是无法控制回滚,今天看大牛的博客发现,问题远远不只如此。 具体总结下来是以下3个问题 1、内层事务回滚...

买个ZIPPO点蚊香
2016/01/06
188
0

没有更多内容

加载失败,请刷新页面

加载更多

[转] Java 无界阻塞队列 DelayQueue 入门实战

原文出处:http://cmsblogs.com/ 『chenssy』 DelayQueue是一个支持延时获取元素的无界阻塞队列。里面的元素全部都是“可延期”的元素,列头的元素是最先“到期”的元素,如果队列里面没有元...

泥瓦匠BYSocket
21分钟前
5
0
zk中集群版中角色和消息类型

服务器角色 LEADER LEARNER FOLLOWING OBSERVER 消息类型 数据同步 服务器初始化 请求处理型 会话管理型 LEADER 集群工作核心,作用有: 1事务请求唯一调度和处理者,保证事务处理顺序性 2集...

writeademo
22分钟前
3
0
阿里云推送的基本使用-Swift;iOS10+

func initCloudPush(){ CloudPushSDK.asyncInit("*****", appSecret: "*******") { (result) in if result!.success{ print("deviceId===......

west_zll
34分钟前
4
0
分布式及高可用元数据采集原理

转载本文需注明出处:微信公众号EAWorld,违者必究。 引言: 元数据采集是元数据产品的核心部分,如何提升采集效率是需要仔细斟酌的事情,既要保持稳定性也要保持跟上主流技术的发展趋势。元...

EAWorld
49分钟前
5
0
为构建社交关系链手淘都做了啥?

作者|王卫(泓冰) 出品|阿里巴巴新零售淘系技术部 01、淘宝社交关系推荐的背景 1、互联网下半场到来:互联网的下半场,人口红利消失,各大平台需要对用户做精细化运营,用户的增长和留存是每一...

阿里云官方博客
50分钟前
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部