因为前几天看一个项目文档出现“本系统采用基于Spring的声明式事务控制”,才根据文档和代码了解了一下事务管理的相关知识。这里对自己的学习做个总结。
一:相关概念
1.事务:事务是一系列的动作,它们综合在一起才是一个完整的工作单元,这些动作必须全部完成,如果有一个失败的话,那么事务就会回滚到最开始的状态,仿佛什么都没发生过一样。用来确保数据的完整性和一致性。
2.事务的四个特性:原子性,一系列动作为一个整体,要么都完成,要么都不完成。一致性,事务完成后不管成功还是失败,它所处理的业务涉及的数据要保持一致,不能一些改变了一些没有改变。隔离性,就是说当一个事务没有全部完成并提交之前,它所做的一切处理导致的结果比如数据的变化不会被其他事务看到。持久性:就是说一旦事务完成,它的结果就不受其他的影响例如系统崩溃之类的产生变化,通常事务的结果被存储在持久化容器例如数据库中。
3.事务管理的内容:
注:spring中事务管理的结构。
1)定义事务的基本属性:事务超时(事务最长持续时间,当事务超出设置的最长持续时间还未完成的话会自动进行回滚。)、是否只读(设置为只读的事务不会修改任何数据)、传播行为(当事务被另一个事务调用时是在现有事务中运行还是新开一个事务运行)、隔离规则(设置未提交的事务所修改的数据是否会被其他事务看到)、回滚规则(定义哪些异常会导致事务回滚哪些则不用回滚)。spring中定义事务的接口为TransactionDefinition,此外,它也能获得事务属性状态等。
2)事务管理器会一直监控事务的状态,并对不同的事务状态做出处理,状态有是否是新事务、是否有恢复点、设置为只回滚,是否为只回滚,是否已完成等。Spring监控事务状态的接口是TransactionStatus,调用这个接口的方法是getTransaction()。
3)事务管理器监控到事务的状态之后就会对事务做出相应处理,事务管理器能够做的处理有:事务回滚(rollback())、事务提交(commit())、事务状态获得(getTransaction())。
注:注:Spring并不直接管理事务,它是根据项目所使用的持久化框架把事务委托给相关框架的事务管理器来实现,所以事务管理器会对事务做出什么样的处理是和所使用的持久化框架和监控到的事务的参数来决定的。
Spring管理事务的接口是PlatformTransactionManager。这个接口为JDBC、hibernate、JPA、JTA等提供了对应的事务管理器。
4)JPA:JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。
5)JTA:JTA允许应用程序执行分布式事务处理——在两个或多个网络计算机资源上访问并且更新数据。(J2EE平台使用)。
(疑惑:spring的事务管理机制是把事务管理委托给持久化框架的事务管理器去做,还是给不同的框架提供不同的它自己的管理器去管理?我自己的理解:就是说 它只是对其他框架的事务管理进行配置,使之有统一的编程或者说使用模型,但是实际的事务管理还是由框架来完成的。需要看一下配置的事务是spring提供的类还是其它的框架提供的。但是像mybatis这类的框架并没有包含在spring提供的事务管理器里面啊,这种又怎么办呢?我看的项目用的JPA事务管理,但是持久化框架是mybatis,这样又是怎么回事呢?)
二:声明式事务管理步骤(全注解方式)
1.在spring的配置文件中引入<tx:>命名空间。
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"
default-lazy-init="false">
2.在配置文件中定义事务管理器,不同的持久化框架的事务管理器不同。其中entityManagerFactory是spring的实体管理器工厂。
<!-- 定义事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- <property name="dataSource" ref="jndiDataSource" /> -->
<property name="persistenceUnitName" value="app_db_unit" />
<property name="persistenceXmlLocation" value="classpath:persistence-app.xml" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="${hibernate.dialect}" />
</bean>
</property>
</bean>
3.开启spring提供的基于注解的声明式事务管理,使具有@Transactional 注解的bean自动配置为声明式事务支持。
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
4.然后在dao层需要的类或接口前边加上注解(我想应该是有关数据库操作的类才行吧),这样就算好了。
注:被transactional注解的类只能被public修饰。
5.设置事务属性。类似下图。
三:参考文章。
Spring事务管理(详解+实例):http://www.mamicode.com/info-detail-1248286.html
Spring学习8-Spring事务管理(注解式声明事务管理):http://blog.sina.com.cn/s/blog_7ffb8dd501014e0f.html