hellotoday的gravatar头像
hellotoday 2018-03-24 16:53:04

service方法内部事务如何控制?

现在要在service中的一个方法中调用多个接口,可能是内部接口也可能是外部接口,可能是操作数据库,也可能是操作其他资源,怎么实现让这个方法保证事务的一致性,实现事务回滚等。

所有回答列表(2)
膜拜java的gravatar头像
膜拜java  LV6 2018年3月25日

spring有事务控制机制,分编码式事务、和注解式事务。个人推荐注解式的。

只要给service加上注解即可。通过注解还能加很多隔离级别。具体内容可以查阅:Transactional

 

kaka的gravatar头像
kaka  LV19 2018年3月28日

我觉得这个还是要看你自己的业务了,你先要清楚你的业务是否需要全部回滚,然后还要明白事务的传播性和隔离性,我拿spring的事务给你举例下

spring事务的传播性:

propagation_requried spring的默认传播机制,如果外层有事务则当前事务加入到外层事务,一块提交一块回滚,如果外层没有事务则当前开启一个新事务
propagation_requried_new,该传播机制是每次新开启一个事务,同时把外层的事务挂起,当前新事务执行完毕后在恢复上层事务的执行。
propagation_supports,该传播机制如果外层有事务则加入该事务,如果不存在也不会创建新事务,直接使用非事务方式执行
propagation_not_supported,该传播机制不支持事务,如果外层存在事务则挂起外层事务 ,然后执行当前逻辑,执行完毕后,恢复外层事务
propagation_never该传播机制不支持事务,如果外层存在事务则直接抛出异常
propagation_mandatory该传播机制是说配置了该传播性的方法只能在已经存在事务的方法中被调用,如果在不存在事务的方法中被调用,会抛出异常
propagation_nested该传播机制特点是可以保存状态保存点,当事务回滚后会回滚到某一个保存点上,从而避免所有嵌套事务都回滚

你了解完上面这些传播性后,就可以根据自己的业务需要配置事务的传播性来控制事务的回滚

回到你的问题上,你这种service嵌套调用里,每一个service是否都使用了事务,每个service的事务设置的传播性是什么,然后对照上面每种传播性去分析吧。

最后关于事务的配置很简单,有基于注解的,也有基于xml的,我们项目中的事务控制在service层,用的是xml方式,你参考下:

<!-- 配置事务管理器 -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>
 
	<!-- 配置事务属性 -->
	  <tx:advice id="transactionAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="add*" propagation="REQUIRED" />
			<tx:method name="append*" propagation="REQUIRED" />
			<tx:method name="insert*" propagation="REQUIRED" />
			<tx:method name="save*" propagation="REQUIRED" />
			<tx:method name="batchSave*" propagation="REQUIRED" />
			<tx:method name="update*" propagation="REQUIRED" />
			<tx:method name="modify*" propagation="REQUIRED" />
			<tx:method name="edit*" propagation="REQUIRED" />
			<tx:method name="delete*" propagation="REQUIRED" />
			<tx:method name="remove*" propagation="REQUIRED" />
			<tx:method name="repair" propagation="REQUIRED" />
			<tx:method name="delAndRepair" propagation="REQUIRED" />
			<tx:method name="get*" propagation="SUPPORTS" />
			<tx:method name="find*" propagation="SUPPORTS" />
			<tx:method name="load*" propagation="SUPPORTS" />
			<tx:method name="search*" propagation="SUPPORTS" />
			<tx:method name="datagrid*" propagation="SUPPORTS" />
			<tx:method name="*" propagation="SUPPORTS" />
		</tx:attributes>
	</tx:advice>

上面的propagation属性就是配置spring事务的传播性,我贴一段spring-tx-4.0.xsd中的定义给你看下,是不是对应了我上面解释的7种传播性,希望能解决你的疑问

<xsd:attribute name="propagation" default="REQUIRED">
	<xsd:annotation>
	        <xsd:documentation source="java:org.springframework.transaction.annotation.Propagation"><![CDATA[The transaction propagation behavior.]]></xsd:documentation>
	</xsd:annotation>
	<xsd:simpleType>
		<xsd:restriction base="xsd:string">
		    <xsd:enumeration value="REQUIRED"/>
		    <xsd:enumeration value="SUPPORTS"/>
	            <xsd:enumeration value="MANDATORY"/>
		    <xsd:enumeration value="REQUIRES_NEW"/>
		    <xsd:enumeration value="NOT_SUPPORTED"/>
		    <xsd:enumeration value="NEVER"/>
		    <xsd:enumeration value="NESTED"/>
		</xsd:restriction>
	</xsd:simpleType>
</xsd:attribute>

 

 

顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友