spring的事务详解

如果不想看概念的话,直接跳到编程式事务管理(ctrl+F)那里开始

事务的四大特性:

原子性,一致性,隔离性,持久性

原子性是指事务是一个不可分割的工作单位,十五中的操作要么都发生,要么都不发生。

一致性是指事务前后数据的完整性必须保持一致。

隔离性是指多个用户并发访问数据库时,一个用户的食物不能被其他用户的事务所干扰,多个并发事务之间数据要相互隔离。

持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,即使数据库发生故障也不应该对齐有任何影响。

 

Spring事务管理高层抽象主要包括3个接口

PlatformTransactionManager(事务管理器)

TransactionDefinition(事务定义信息[隔离,传播,超时,只读])

TransactionStatus(事务具体运行状态)

 

PlatformTransactionManager接口实现

Org.springframework.jdbc.datasource.DataSourceTransactionManager(使用spring jdbc或ibatis进行持久化数据时使用)

Org.springframework.orm.hibernate3.HibernateTransactionManager(使用Hibernate3.0版本进行持久化数据)

Org.springframework.orm.jpa.JpaTransactionManager(使用JPA进行持久化时使用)

Org.springframework.jdo.JdoTransactionManager(当持久化机制是Jdo时使用)

Org.springframework.transaction.jta.JtaTransationManager(使用一个JTA实现来管理事务,在一个事务跨越多个资源时必须使用)

 

如果不考虑隔离性,会引发安全问题:

脏读,不可重复读,幻读

脏读:一个事务读取了另一个事务改写但还未提交的数据,如果这些数据被回滚,则读到的数据是无效的

不可重复读:在同一事务中,多次读取同一数据返回的结果有所不同

幻读:一个事务读取了几行记录后,另一个事务插入一些记录,幻读就发生了,再后来的查询中,第一个事务就会发现有些原来没有的记录

 

事务隔离级别(四种)

Default(使用后端数据库默认的隔离级别)

READ_UNCOMMITED(允许你读取还未提交的改变了的数据。可能导致脏,幻,不可重复读)

READ_COMMITTED(允许在并发事务已经提交后读取,可防止脏读,但幻读和不可重复读仍会发生)

REPEATABLE_READ(对相同字段的多次读取是一致的,除非数据被事务本身改变。可防止脏,不可重复读,但幻读扔可能发生)

SERIALIZABLE(完全服从ACID的隔离级别,确保不发生脏,幻,不可重复读,这在所有隔离级别中是最慢的,它是典型的通过完全锁定在事务中涉及的数据表来完成的)

 

PS:

Mysql默认采用REPEATABLE_READ隔离级别

Oracle默认采用READ_COMMITTED隔离级别

 

事务的传播行为(七种):

PROPAGATION_REQUIRED(支持当前事务,如果不存在,就新建一个)

PROPAGATION_SUPPORTS(支持当前事务,如果不存在,就不使用事务)

PROPAGATION_MANDATORY(支持当前事务,如果不存在,抛出异常)

PROPAGATION_REQUIRES_NEW(如果有事务存在,挂起当前事务,创建一个新的事务)

PROPAGATION_NOT_SUPPORTED(以非事务方式运行,如果有事务存在,挂起当前事务)

PROPAGATION_NEVER(以非事务方式运行,如果有事务存在,跑出异常)

PROPAGATION_NESTED(如果当前事务存在,则嵌套事务执行)

 

Spring支持两种方式事务管理

--编程式的事务管理(一种)

       *在实际应用中很少使用

       *通过TransactionTemplate手动管理事务

--使用XML配置声明式事务(三种)

       *开发中推荐使用(代码入侵性最小)

       *Spring的声明式事务是通过AOP实现的

 

编程式的事务管理:

Spring文件配置

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

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

<!--配置业务层类-->
<bean id=”accountService” class=”cn.muke.spring.demo1.AccountServiceImpl”>
<property name=”accountDao” ref=”accountDao”/>
<!--注入事务管理的模板 -->
<property name=”transactionTemplate” ref=”transactionTemplate”/>
</bean>

在业务实现类里面(serviceimpl)

//注入事务管理的模板:
Private TransactionTemplate transactionTemplate;

Public void transfer(String out,String in,double money){
TransactionTemplate.execute(new TransactionCallbackWithoutResult(){
Protected void doInTransactionWithoutResult(TransactionStatus transactionStatus){
AccountDao.outMoney(out,money);
Int i=1/0;
AccountDao.inMoney(in,money);
}
});
}
执行这个方法会失败,因为1/0会错误所以会回滚

声明式事务管理方式一:基于TransactionProxyFactoryBean的方式

Spring文件配置

<!--配置事务管理器 -->
<bean id=”transactionManager” class=”org.springframework.jdbc.datasource.DataSourceTransactionMnager”>
<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的格式:
*代表类中所有方法 
*PROPAGATION :事务的传播行为
*ISOLATION:事务的隔离级别
*readOnly:只读(不可以进行插入,修改删除)
*-Exception:发生哪些异常回滚事务
*+Exception:发生哪些异常不回滚事务
-->
<prop key=”transfer”> PROPAGATION </prop>
</props>
</property>
</bean>

声明式事务管理方式二:基于AspectJ的XML方式

Spring文件配置

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

<!--配置事务的通知:(事务的增强)-->
<tx:advice id=”txAdvice”transaction-manager=”transactionManager”>
<tx:attributes>
<!--
	Propagation:事务传播行为
	Isolation:事务隔离级别
	Read-only:只读
	Rollback-for:发生哪些异常回滚
	No-rollback-for:发生哪些异常不会滚
	Timeout”过期信息
 -->

<tx:method name=”transfer” propagation=”REQUIRED”/>
</tx:attributes>
</ tx:advice >

<!--配置切面-->
<aop:config>
<!--配置切入点-->
<aop:pointcut expression=”execution(* cn.muke.spring.demo3.AccountService+.*(..))” id=”pointcut1”>
<!--配置切面-->
<aop:advisor advice-ref=”txAdvice” pointcut-ref=”pointcut1”/>
</aop:config>

声明式事务管理方式三:基于注解方式

Spring文件配置

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

<!--开启注解事务 -->
<tx:annotation-driven transaction-manager=”transactionManager”/>

在业务实现类里面(serviceimpl)

加上@Transactional即可
@Transactiona注解中的属性
Propagation:事务的传播行为
Isolation:事务的隔离级别
ReadOnly:只读
RollbackFor:发生哪些异常回滚
NoRollbackFor:发生哪些异常不回滚
例如:Transactiona(propagation=Propagation.REQUIRED,isolation=Isolation.Default)
总结:
--编程式的事务管理
	*通过TransactionTemplate手动管理事务(很少使用)
--使用XML配置声明式事务
	*基于TransactionProxyFactoryBean的方式(很少使用)
		*需要为每个进行事务管理的类,配置一个TransactionProxyFactoryBean进行增强
	*基于AspectJ的XML方式(经常使用)
		*一旦配置好了,需要在类上加任何东西
	*基于注解方式(经常使用)
		*配置简单。需要在业务类上添加一个@Transactiona的注解










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值