详解spring中的事务管理(编程式的事务管理,声明式的事务管理)

spring提供的事务管理API

1. PlatformTransactionManager:平台事务管理器.

	commit(TransactionStatus status) 
	getTransaction(TransactionDefinition definition) 
	rollback(TransactionStatus status) 

2. TransactionDefinition:事务定义

	ISOLation_XXX:事务隔离级别.
	PROPAGATION_XXX:事务的传播行为.
	过期时间:

3. TransactionStatus:事务状态

	是否一个新的事务
	事务是否已经提交

这三者之间的关系: PlatformTransactionManager通过TransactionDefinition设置事务相关信息管理事务,管理事务过程中,产生一些事务状态:状态由TransactionStatus记录.

PlatformTransactionManager:接口.
Spring为不同的持久化框架提供了不同PlatformTransactionManager接口实现

1. org.springframework.jdbc.datasource.DataSourceTransactionManager :
使用Spring JDBC或iBatis 进行持久化数据时使用

2. org.springframework.orm.hibernate3.HibernateTransactionManager:
使用Hibernate3.0版本进行持久化数据时使用

spring支持的两种事务管理:

1. 编程式的事务管理:
在实际中很少用到。 通过Transaction手动管理事务

2. 声明式的事务管理:
在实际中推荐使用(代码侵入量少),spring的声明式事务管理是通过AOP实现的。

编程式的事务管理:

	<!-- 业务层类 -->
	<bean id="accountService" class="org.westos.demo1.AccountServiceImpl">
		<!-- 在业务层注入Dao -->
		<property name="accountDao" ref="accountDao"/>
	</bean>
	
	<!-- 持久层类 -->
	<bean id="accountDao" class="org.westos.demo1.demo1.AccountDaoImpl">
		<!-- 注入连接池的对象,通过连接池对象创建模板. -->
		<property name="dataSource" ref="dataSource"/>
	</bean>

需要事务管理器:真正管理事务对象.

  • Spring提供了事务管理的模板(工具类.)

第一步: 配置事务管理器

<!-- 配置事务管理器 -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<!-- 需要注入连接池,通过连接池获得连接 -->
		<property name="dataSource" ref="dataSource"/>
	</bean>

第二步:配置事务模板类(TransactionTemplate)

	<!-- 事务管理的模板 -->
	<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
		<property name="transactionManager" ref="transactionManager"/>
	</bean>

第三步:在业务层注入模板:(通过模板管理事务)

	<!-- 业务层类 -->
	<bean id="accountService" class="org.westos.demo1.demo1.AccountServiceImpl">
		<!-- 在业务层注入Dao -->
		<property name="accountDao" ref="accountDao"/>
		<!-- 在业务层注入事务的管理模板 -->
		<property name="transactionTemplate" ref="transactionTemplate"/>
	</bean>

第四步:在业务层代码上使用模板:


	public void transfer(final String from, final String to, final Double money) {
		transactionTemplate.execute(new TransactionCallbackWithoutResult() {
			@Override
			protected void doInTransactionWithoutResult(TransactionStatus status) {
				accountDao.out(from, money);
				int d = 1 / 0;
				accountDao.in(to, money);
			}
		});
	}

缺点: 代码量增加,代码有侵入性。

声明式事务管理

1. 原始方式(基于TransactionProxyFactoryBean)

原理:spring的配置文件对业务中需要进行事务管理的类生成一个TransactionProxyFactoryBean代理对象,来进行事务管理。

第一步:创建事务管理器:

	<!-- 事务管理器 -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<!-- 注入连接池 -->
		<property name="dataSource" ref="dataSource"/>
	</bean>

第二步:创建代理对象:

	<!-- 配置生成代理对象 -->
	<bean id="accountServiceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
		<!-- 目标对象 -->
		<property name="target" ref="accountService"/>
		<!-- 注入事务管理器 -->
		<property name="transactionManager" ref="transactionManager"/>
		<!-- 事务的属性设置 -->
		<property name="transactionAttributes">
			<props>
				<prop key="transfer">PROPAGATION_REQUIRED</prop>
			</props>
		</property>
	</bean>

第三步:编写测试类:

@Autowired
//注意注入的是代理对象
@Qualifier("accountServiceProxy")
private AccountService accountService;

public void test1(){
	accountService.in(from,money);
}

缺点: 就是需要为每一个管理事务的类生成代理.需要为每个类都需要进行配置.

2.在(1)中的原始方式上有所改进(自动代理.基于切面):
原理:同样和(1)中一样也是生成一个代理对象来实现事务管理,但是使用了自动代理这样就改进了(1)中的缺点,不需要每一个需要事务管理的类都配置生成代理对象。

第一步:配置事务管理器:

	<!-- 事务管理器 -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"/>
	</bean>

第二步:定义一个通知类:

	<!-- 定义一个增强 -->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<!-- 增强(事务)的属性的配置 -->
		<tx:attributes>
			<!-- 
				isolation:DEFAULT	:事务的隔离级别.
				propagation			:事务的传播行为.
				read-only			:false.不是只读
				timeout				:-1
				no-rollback-for		:发生哪些异常不回滚
				rollback-for		:发生哪些异常回滚事务
			 -->
			<tx:method name="transfer"/>
		</tx:attributes>
	</tx:advice>

第三步:切点和通知的结合:

	<!-- aop配置定义切面和切点的信息 -->
	<aop:config>
		<!-- 定义切点:哪些类的哪些方法应用增强 -->
		<aop:pointcut expression="execution(* org.westos.demo1.AccountService+.*(..))" id="mypointcut"/>
		<!-- 定义切面: -->
		<aop:advisor advice-ref="txAdvice" pointcut-ref="mypointcut"/>
	</aop:config>

3:基于注解的声明式事务管理:

第一步:配置事务管理器:

	<!-- 事务管理器 -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource"/>
	</bean>

第二步:启用事务管理的注解:

	<!-- 开启注解的事务管理 -->
	<tx:annotation-driven />

第三步:在业务类中所需要事务管理的方法上使用注解:

@Transactional
	//注解中有属性值:
	//isolation
	//propagation
	// readOnly

@Transactional注解详解:
默认情况下,只有方法出现的 是RuntimeException或Error以及它们的子类时(未检查异常),才会导致事务回滚

如果要改变默认情况
@Transactional(rollbackFor=异常类.class)
那么方法如果出现了该异常,或该异常的子类异常时,就会回滚

@Transactional(noRollbackFor=异常类.class)
当遇到这种异常时,不会回滚事务

最后要注意的是,在业务方法中不要自己try-catch捕获异常,否则spring无法自动回滚事务

@Transactional(isolation = 隔离级别)

@Transactional(timeout = 超时时间(秒))

@Transactional(readOnly = true|false) true表示只读(只有查询) false(会有增删改)设置为true,性能会有所提升,但是底层数据库驱动支持(对mysql支持)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值