事务的特性: 原子性、一致性、隔离性、持久性
(1)原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生
(2)一致性是指事物前后数据的完整性必须保持一致
(3)隔离性是指多个用户并发访问数据库时,一个用户的事务不能被其他用户的事务干扰,多个并发事务之间数据要相互隔离。
(4)持久性是指一个事务一旦被提交,它对数据库中数据的改变是永久性的,即使数据库发生故障也不应该对其有任何影响
Spring事务管理接口
PlatfromTransactionManager 事务管理器
TransactionDefinition 事务定义信息(隔离、传播、超时、只读)
TransactionStatus 事务具体运行状态
事务管理器 PlatformTransactionManager
事务的传播行为
Spring配置事务管理器(编程式)
(1)在配置文件中配置事务管理器
<!-- 配置c3p0连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="...">
<!-- 以下省略 -->
</bean>
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource">
</bean>
<!-- 配置事务管理的模版:Spring为了简化事务管理的代码而提供的类 -->
<bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager"></property>
</bean>
(2) 在需要事务管理的业务类中,注入事务管理模版
private TransactionTemplate transactionTemplate;
(3) 在具体方法中使用
transactionTemplate.execute(new TransactionCallbackWithoutResult()
{
protected void doInTransactionWithoutResult(TransactionStatus transactionStatus)
{
//需要在事务中进行的操作
}
});
显而易见,编程式的事务管理需要手动地改写业务逻辑代码,非常麻烦,因此在实际项目中不常使用。
Spring配置事务管理器(声明式,XML方式)
(1)在配置文件中配置事务管理器
<!-- 配置c3p0连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="...">
<!-- 以下省略 -->
</bean>
<!-- 配置事务管理器 -->
<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>
<!-- 注入事务管理器 -->
<property name="transactionManager" ref="transactionManager"></property>
<!-- 注入事务的属性 -->
<property name="transactionAttributes">
<props>
<!-- prop的格式:
<prop key=“方法名”>传播行为,隔离级别,readOnly,-Exception,+Exception</prop>
事务的属性如下:
*PROPAGATION :事务的传播行为
*ISOLATION :事务的隔离级别
*readOnly :只读.(不可以进行修改,插入,删除)
*-Exception :发生哪些异常回滚事务
*+Exception :发生哪些异常不回滚事务
-->
<prop key="transfer">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
(2) 在使用AccountService时,不要注入AccountService, 而是直接使用它的代理类
@Resource(name=“accountServiceProxy”)
private AccountService accountService;
因为要对每一个要进行事务管理的类进行配置,因此在实际使用中也不常用
Spring配置事务管理器(声明式,ApectJ方式)
(1)在配置文件中配置事务管理器
<!-- 配置c3p0连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="...">
<!-- 以下省略 -->
</bean>
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<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>
(2)在使用AccountService时,进行注入
@Resource(name=“accountService”)
private AccountService accountService
Spring配置事务管理器(声明式,注解方式)
(1)在配置文件中配置事务管理器
<!-- 配置c3p0连接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="...">
<!-- 以下省略 -->
</bean>
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource">
</bean>
<!-- 开启注解事务 -->
<tx:annotation-driven transaction-manager="transactionManager" />
(2) 在需要事务的业务层类上加上注解
/**
@Transactional注解中的属性:
propagation: 事务的传播行为
isolation : 事务的隔离级别
readyOnly : 只读
rollbackFor: 发生哪些异常回滚
noRollbackFor:发生哪些异常不回滚
*/
@Transactional(propagation=Propagation.REQUIRED)
public class AccountServiceImpl implements AccountService
{
}
(3)在使用AccountService时,进行注入
@Resource(name=“accountService”)
private AccountService accountService
总结
Spring将事务管理分成了两类:
* 编程式事务管理:
*手动编写代码进行事务管理(很少使用)
* 声明式事务管理:
*基于TransactionProxyFactoryBean的方式(很少使用)
*需要为每个进行事务管理的类,配置一个TransactionProxyFactoryBean进行增强
*基于AspectJ的XML方式(经常使用)
*配置复杂,但清晰且不需要在类上添加
*基于注解方式(经常使用)
*配置简单. 但需要在业务层类上添加一个@Transactional注解