spring 通过拦截的方式 控制事务,解决多节点高并发的情况下对同一条数据处理的问题

做项目遇到这样一个问题

支付成功之后会有一个回调通知,那边的通知方法是循环持续回调,直到我这边返回成功会停。

因为是多节点的,多个服务器会同时通知。想到这种方式解决:

开启一个事务,查询数据的时候用 select for update 锁定一条数据 , 然后更新状态,提交事务。在线上调试再没出现类似的问题。

涉及到的配置项:

<!-- Declare a transaction manager -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="dataSource" />
<!-- define the SqlSessionFactory, notice that configLocati on is not needed
when you use MapperFactoryBean -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="WEB-INF/mybatis/sqlmap-config.xml" />
</bean>
<!-- scan for mappers and let them be autowired -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.hx.persistence" />
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>

<!-- 定义拦截器,用来指定事物属性,级别,和异常处理 -->
<bean id="transactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager" ref="transactionManager"></property>
<property name="transactionAttributes">
<props>
<!-- PROPAGATION_SUPPORTS: 如果已经存在事务,则加入事务;如果没有事务,则以非事务的方式执行; PROPAGATION_MANDATORY:
使用当前事务, 如果没有, 则抛出异常; PROPAGATION_REQUIRED: 新建事务,如果当前有事务, 则挂起; P ROPAGATION_NOT_SUPPORTED:以非事务的方式执行,
如果当前有事务, 则挂起; PROPAGATION_NEVER:以非事务的方式执行, 如果当前有事务,则抛出异常; +/-Exception</prop>
+ 表示异常出现时事物提交 - 表示异常出现时事务回滚 -->
<prop key="get*">PROPAGATION_SUPPORTS,readOnly</prop>
<prop key="find*">PROPAGATION_SUPPORTS,readOnly</prop>
<prop key="del*">PROPAGATION_REQUIRED,-Exception</prop>
<prop key="update*">PROPAGATION_REQUIRED,-Exception</prop>
<prop key="set*">PROPAGATION_REQUIRED,-Exception</prop>
<prop key="save*">PROPAGATION_REQUIRED,-Exception</prop>
<prop key="create*">PROPAGATION_REQUIRED,-Exception</prop>
</props>
</property>
</bean>
<!-- 用来定义那些类需要采用事物管理 spring 事物的动态代理类 BeanNameAutoProxyCreator 根据类名自动代理,接受表达式 -->
<bean id="BeanProxy"
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<!-- 对类名以Service结尾的类进行代理 -->
<value>*TransactionService*</value>
</property>
<!-- 对代理类进行加载拦截器(实现通知的过程) -->
<property name="interceptorNames">
<list>
<value>transactionInterceptor</value>
</list>
</property>
</bean>

 

posted @ 2018-03-01 16:59  LandauNi  阅读(422)  评论(0)    收藏  举报