一、事务简介##
- 事务管理是企业级应用程序开发中必不可少的技术,用来确保数据的完整性和一致性。
- 事务就是一系列的动作,它们被当作一个单独的工作单元,这些动作要么全部完成,要么全部不起作用。
- 事务的四个关键属性:
① 原子性( atomicity):事务是一个原子操作,由一系列动作组成。事务的原子性确保动作要么全部完成要么全部不起作用。
② 一致性(consistency):一旦所有事务动作完成,事务就被提交。数据和资源就处于一种满足业务规则的一致性状态中。
③ 隔离性(isolation):可能许多事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏。
④ 持久性(durability):一旦事务完成,无论发生什么系统错误,它的结果都不应该受到影响。通常情况下,事务的结果被写到持久化存储器中。 - 举个例子:
转账,A 给 B 转 500 块钱,这时候需要有两个操作,A的账户 -500 块,B的账户 +500块,要么都完成,要么都不完成。如果只完成一部分,数据就被破坏了,要么就是 500 块没了,要么就是凭空多了 500 块。
##二、 Spring中的事务管理 ##
- 作为企业级应用程序框架,Spring 在不同的事务管理API之上定义了一个抽象层,而应用程序开发人员不必了解底层的事务管理 API,就可以使用 Spring 的事务管理机制。
- Spring既支持编程式事务管理,也支持声明式的事务管理。
- 编程式事务管理:将事务管理代码嵌入到业务方法中来控制事务的提交和回滚。在编程式管理事务时,必须在每个事务操作中包含额外的事务管理代码。
声明式事务管理
:大多数情况下比编程式事务管理更好用。它将事务管理代码从业务方法中分离出来,以声明的方式来实现事务管理。事务管理作为一种横切关注点,可以通过 AOP 方法模块化。Spring 通过Spring AOP 框架支持声明式事务管理。- Spring 从不同的事务管理API中抽象了一整套的事务机制。开发人员不必了解底层的事务 API,就可以利用这些事务机制。有了这些事务机制,事务管理代码就能独立于特定的事务技术了。
- Spring 的核心事务管理抽象是
Interface PlatformTranscationManager
管理封装了一组独立于技术的方法。无论使用Spring的哪种事务管理策略(编程式或声明式),事务管理都是必须的。
##三、Spring中事务管理的不同实现##
- Class
DataSourceTransactionManager
:在应用程序中只需要处理一个数据源,而且通过 JDBC 存取。 - Class
JtaTransactionManager
:在 JavaEE 应用服务器上用 JTA(Java Transaction API) 进行事务管理。 - Class
HibernateTransactionManager
:用 Hibernate 框架存取数据库。 - 事务管理器以普通的Bean形式声明在 Spring IOC容器中。
##四、Spring声明式事务##
- Spring允许使用
@Transactional
注解来标注事务方法。 - 为了将方法定义为支持事务处理的,可以为方法添加 @Transactional 注解。根据 Spring AOP 基于代理机制,只能标注公有方法。
- 可以在方法或类级别上添加 @Transactional 注解。把这个注解应用到类上时,这个类中所有公共方法都会被定义成支持事务处理的。
- 在Bean配置文件中配置事务管理器。
- 在Bean配置文件中只需要启用
<tx:annotation-driven>
元素,并为之指定事务管理器就可以了。 - 如果事务管理器的名称是
transactionManager
,就可以在<tx:annotation-driven>
元素中省略 transaction-manager 属性。这个元素会自动检测该名称的事务管理器。 - 举个例子:
/**
* 使用 @Transactional 指定事务方法
*/
@Service("bookShopService")
public class BookShopServiceImpl implements BookShopService
{
@Transactional
public void purchaseSigleBook(String acctName, String bookId)
{
...
}
}
<!-- 配置事务管理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 启用事务注解 -->
<tx:annotation-driven transaction-manager="transactionManager"/>