版權聲明:本文爲博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/damoneric_guo/article/details/69384968
什麼是分佈式事務?
分佈式事務,說的就是JTA(XA)的事務,只要你能回答出來兩段式提交,基本就算你過了,在J2EE企業開發場景比較常用,跨數據庫跨應用,準備階段,提交階段,這些,做互聯網開發的用的比較少,不過因爲JTA是事務標準,spring的事務也要基於這個標準來實現,所以瞭解一些對於開發是有好處的,所以纔會問。
什麼是分佈式鎖?
第二個好一些,分佈式鎖應用場景很多,比如併發場景下對於數據庫的更改,或者分佈式運行的JOB之類的,都需要一個分佈式的鎖來讓多機對於競爭資源實現序列化的訪問,然後實現的話現在通過zookeeper實現的比較多見(但是性能不是很好),也可以通過公用的緩存或者數據庫自己來實現。
爲了解決併發的問題,需要用到redis分佈式事務鎖。(會用纔是王道!!!)
redis分佈式事務鎖案例配置:
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="XX.XX.*" />
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
<bean id="disconfMgrBean" class="com.baidu.disconf.client.DisconfMgrBean"
destroy-method="destroy">
<property name="scanPackage" value="com.niwodai.tc"></property>
</bean>
<bean id="disconfMgrBean2" class="com.baidu.disconf.client.DisconfMgrBeanSecond"
init-method="init" destroy-method="destroy" />
<!-- 使用託管方式的disconf配置(無代碼侵入, 配置更改會自動reload) -->
<bean id="configproperties_disconf"
class="com.baidu.disconf.client.addons.properties.ReloadablePropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath*:job.properties</value>
<value>classpath*:redis.properties</value>
<value>classpath*:dubbo-pvd.properties</value>
<value>classpath*:dubbo-consumer.properties</value>
<value>classpath*:active-MQ.properties</value>
</list>
</property>
</bean>
<!-- 配置線程池 -->
<!-- <bean id="startTransferThreadPool"
class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
線程池維護線程的最少數量
<property name="corePoolSize" value="${corePoolSize}" />
線程池維護線程所允許的空閒時間
<property name="keepAliveSeconds" value="${keepAliveSeconds}" />
線程池維護線程的最大數量
<property name="maxPoolSize" value="${maxPoolSize}" />
線程池所使用的緩衝隊列
<property name="queueCapacity" value="${queueCapacity}" />
</bean> -->
<bean id="propertyConfigurerForProject1"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreResourceNotFound" value="true" />
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="propertiesArray">
<list>
<ref bean="configproperties_disconf" />
</list>
</property>
</bean>
<!-- 引入系統中當前環境下所有的properties文件 -->
<bean id="propertyPlaceholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="locations">
<list>
<value>classpath*:properties/*.properties</value>
</list>
</property>
</bean>
<import resource="classpath*:spring/dataSource.xml" />
<import resource="classpath*:spring/mybatis.xml" />
<!-- <import resource="classpath*:spring/mybatis-config.xml" /> -->
<import resource="classpath*:spring/service.xml" />
<import resource="classpath*:spring/facade.xml" />
<import resource="classpath*:spring/dubbo-common.xml" />
<import resource="classpath*:spring/dubbo-consumer.xml" />
<import resource="classpath*:spring/dubbo-product-consumer.xml" />
<import resource="classpath*:spring/dubbo-member-consumer.xml" />
<import resource="classpath*:spring/dubbo-msg-consumer.xml" />
<import resource="classpath*:spring/repay-redis.xml" />
<import resource="classpath*:spring/spring-activeMQ.xml" />
<import resource="classpath*:spring/dubbo-cpn-consumer.xml" />
<import resource="classpath*:disconf/spring/notify/notification-client-jms.xml" />
<import resource="classpath*:disconf/spring/notify/notification-client-mail-jms.xml" />
<import resource="classpath*:spring/job/job-*.xml" />
<import resource="classpath*:spring/applicationContext-account-postmq.xml" />
</beans>
repay-redis.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">
<!-- redis配置 -->
<bean id="stringJedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" destroy-method="destroy"
p:host-name="${repay.string.redis.host}" p:port="${repay.string.redis.port}" p:timeout="${repay.string.redis.timeout}" p:usePool="${repay.string.redis.usePool}"
p:password="${repay.string.redis.password}">
<constructor-arg index="0" ref="stringJedisPoolConfig" />
</bean>
<bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate"
p:connection-factory-ref="stringJedisConnectionFactory" p:enableTransactionSupport="false"/>
<bean id="stringJedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="${repay.string.redis.maxTotal}" />
<property name="maxIdle" value="${repay.string.redis.maxIdle}" />
<property name="minIdle" value="${repay.string.redis.minIdle}" />
<property name="maxWaitMillis" value="${repay.string.redis.maxWaitMillis}" />
<property name="testOnBorrow" value="${repay.string.redis.testOnBorrow}" />
<property name="softMinEvictableIdleTimeMillis" value="500" />
<property name="timeBetweenEvictionRunsMillis" value="1000" />
</bean>
</beans>
參數配置:
repay.string.redis.host=192.168.0.172
repay.string.redis.port=6379
repay.string.redis.timeout=15000
repay.string.redis.usePool=TRUE
repay.string.redis.password=123
#repay.string.redis.database=2
repay.string.redis.maxTotal=100
repay.string.redis.maxIdle=50
repay.string.redis.minIdle=20
repay.string.redis.maxWaitMillis=10000
repay.string.redis.testOnBorrow=TRUE
java代碼:
@Resource(name = "stringRedisTemplate")
private StringRedisTemplate stringRedisTemplate;
String key = "A_" + realPayer.getLid();//程序唯一key
// REDIS鎖住在線還款,避免併發問題()
if (stringRedisTemplate.opsForValue().setIfAbsent(key, realPayer.getLid().toString())) {
stringRedisTemplate.expire(key, 5, TimeUnit.MINUTES);
} else {
throw new BusinessException("");
}
try {
//邏輯處理
} catch (Exception e) {
} finally {
stringRedisTemplate.delete(key);
}
謹記 不管處理如何都要有 finally {
stringRedisTemplate.delete(key);
}
maven 包:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.6.0.RELEASE</version>
</dependency>
分佈式事務,說的就是JTA(XA)的事務,只要你能回答出來兩段式提交,基本就算你過了,在J2EE企業開發場景比較常用,跨數據庫跨應用,準備階段,提交階段,這些,做互聯網開發的用的比較少,不過因爲JTA是事務標準,spring的事務也要基於這個標準來實現,所以瞭解一些對於開發是有好處的,所以纔會問。
什麼是分佈式鎖?
第二個好一些,分佈式鎖應用場景很多,比如併發場景下對於數據庫的更改,或者分佈式運行的JOB之類的,都需要一個分佈式的鎖來讓多機對於競爭資源實現序列化的訪問,然後實現的話現在通過zookeeper實現的比較多見(但是性能不是很好),也可以通過公用的緩存或者數據庫自己來實現。
爲了解決併發的問題,需要用到redis分佈式事務鎖。(會用纔是王道!!!)
redis分佈式事務鎖案例配置:
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="XX.XX.*" />
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
<bean id="disconfMgrBean" class="com.baidu.disconf.client.DisconfMgrBean"
destroy-method="destroy">
<property name="scanPackage" value="com.niwodai.tc"></property>
</bean>
<bean id="disconfMgrBean2" class="com.baidu.disconf.client.DisconfMgrBeanSecond"
init-method="init" destroy-method="destroy" />
<!-- 使用託管方式的disconf配置(無代碼侵入, 配置更改會自動reload) -->
<bean id="configproperties_disconf"
class="com.baidu.disconf.client.addons.properties.ReloadablePropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath*:job.properties</value>
<value>classpath*:redis.properties</value>
<value>classpath*:dubbo-pvd.properties</value>
<value>classpath*:dubbo-consumer.properties</value>
<value>classpath*:active-MQ.properties</value>
</list>
</property>
</bean>
<!-- 配置線程池 -->
<!-- <bean id="startTransferThreadPool"
class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
線程池維護線程的最少數量
<property name="corePoolSize" value="${corePoolSize}" />
線程池維護線程所允許的空閒時間
<property name="keepAliveSeconds" value="${keepAliveSeconds}" />
線程池維護線程的最大數量
<property name="maxPoolSize" value="${maxPoolSize}" />
線程池所使用的緩衝隊列
<property name="queueCapacity" value="${queueCapacity}" />
</bean> -->
<bean id="propertyConfigurerForProject1"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreResourceNotFound" value="true" />
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="propertiesArray">
<list>
<ref bean="configproperties_disconf" />
</list>
</property>
</bean>
<!-- 引入系統中當前環境下所有的properties文件 -->
<bean id="propertyPlaceholderConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="locations">
<list>
<value>classpath*:properties/*.properties</value>
</list>
</property>
</bean>
<import resource="classpath*:spring/dataSource.xml" />
<import resource="classpath*:spring/mybatis.xml" />
<!-- <import resource="classpath*:spring/mybatis-config.xml" /> -->
<import resource="classpath*:spring/service.xml" />
<import resource="classpath*:spring/facade.xml" />
<import resource="classpath*:spring/dubbo-common.xml" />
<import resource="classpath*:spring/dubbo-consumer.xml" />
<import resource="classpath*:spring/dubbo-product-consumer.xml" />
<import resource="classpath*:spring/dubbo-member-consumer.xml" />
<import resource="classpath*:spring/dubbo-msg-consumer.xml" />
<import resource="classpath*:spring/repay-redis.xml" />
<import resource="classpath*:spring/spring-activeMQ.xml" />
<import resource="classpath*:spring/dubbo-cpn-consumer.xml" />
<import resource="classpath*:disconf/spring/notify/notification-client-jms.xml" />
<import resource="classpath*:disconf/spring/notify/notification-client-mail-jms.xml" />
<import resource="classpath*:spring/job/job-*.xml" />
<import resource="classpath*:spring/applicationContext-account-postmq.xml" />
</beans>
repay-redis.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">
<!-- redis配置 -->
<bean id="stringJedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" destroy-method="destroy"
p:host-name="${repay.string.redis.host}" p:port="${repay.string.redis.port}" p:timeout="${repay.string.redis.timeout}" p:usePool="${repay.string.redis.usePool}"
p:password="${repay.string.redis.password}">
<constructor-arg index="0" ref="stringJedisPoolConfig" />
</bean>
<bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate"
p:connection-factory-ref="stringJedisConnectionFactory" p:enableTransactionSupport="false"/>
<bean id="stringJedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="${repay.string.redis.maxTotal}" />
<property name="maxIdle" value="${repay.string.redis.maxIdle}" />
<property name="minIdle" value="${repay.string.redis.minIdle}" />
<property name="maxWaitMillis" value="${repay.string.redis.maxWaitMillis}" />
<property name="testOnBorrow" value="${repay.string.redis.testOnBorrow}" />
<property name="softMinEvictableIdleTimeMillis" value="500" />
<property name="timeBetweenEvictionRunsMillis" value="1000" />
</bean>
</beans>
參數配置:
repay.string.redis.host=192.168.0.172
repay.string.redis.port=6379
repay.string.redis.timeout=15000
repay.string.redis.usePool=TRUE
repay.string.redis.password=123
#repay.string.redis.database=2
repay.string.redis.maxTotal=100
repay.string.redis.maxIdle=50
repay.string.redis.minIdle=20
repay.string.redis.maxWaitMillis=10000
repay.string.redis.testOnBorrow=TRUE
java代碼:
@Resource(name = "stringRedisTemplate")
private StringRedisTemplate stringRedisTemplate;
String key = "A_" + realPayer.getLid();//程序唯一key
// REDIS鎖住在線還款,避免併發問題()
if (stringRedisTemplate.opsForValue().setIfAbsent(key, realPayer.getLid().toString())) {
stringRedisTemplate.expire(key, 5, TimeUnit.MINUTES);
} else {
throw new BusinessException("");
}
try {
//邏輯處理
} catch (Exception e) {
} finally {
stringRedisTemplate.delete(key);
}
謹記 不管處理如何都要有 finally {
stringRedisTemplate.delete(key);
}
maven 包:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.6.0.RELEASE</version>
</dependency>