事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。事务通常由高级数据库操纵语言或编程语言(如SQL,C++或Java)书写的用户程序的执行所引起,并用形如begin transaction和end transaction语句(或函数调用)来界定。事务由事务开始(begin transaction)和事务结束(end transaction)之间执行的全体操作组成。
例如:在关系数据库中,一个事务可以是一条SQL语句,一组SQL语句或整个程序。
事务是恢复和并发控制的基本单位。
事务应该具有4个属性:原子性、一致性、隔离性、持续性。这四个属性通常称为ACID特性。
原子性(atomicity)。一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。
一致性(consistency)。事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
隔离性(isolation)。一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
持久性(durability)。持续性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。
spring事务管理相关的接口:
TransactionDefinition:代表一个事物,描述了事务的隔离级别, 超时时间,事务是否只读, 传播规则等等;
TransactionStatus:描述事物的状态;
PlatformTransactionManager:事务管理器接口, 只定义了3个方法:getTransaction()获取事务的状态; commit();rollback();
事务管理器的实现类有多种,根据具体的持久层框架的不同而不同;
spring中的事务传播行为的种类:
PROPAGATION_SUPPORTS: 如果已经存在事务,则加入事务;如果没有事务,则以非事务的方式执行;
PROPAGATION_MANDATORY: 使用当前事务, 如果没有, 则抛出异常;
PROPAGATION_REQUIRED_NEW: 新建事务,如果当前有事务, 则挂起;
PROPAGATION_NOT_SUPPORTED:以非事务的方式执行, 如果当前有事务, 则挂起;
PROPAGATION_NEVER:以非事务的方式执行, 如果当前有事务,则抛出异常;
使用spring声明式的事务管理:
1 把dao,service注入到spring容器(这些dao, service不涉及事务);
2 需要注入一个transactionManager(它需要dataSource);
3 通过TransactionProxyFactoryBean为目标对象(需要事务的dao, service等等)提供事务增强,产生增强后的代理对象.
spring事务管理:
可以通过两种方式实现,一是用AOP来控制事务:
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="sessionFactory"/>
</property>
</bean>
<!-- 配置事务特性 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED"/>
<!--
<tx:method name="add*" propagation="REQUIRED"/>
<tx:method name="del*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="deploy*" propagation="REQUIRED"/>
<tx:method name="submit*" propagation="REQUIRED"/>
<tx:method name="*" read-only="true"/>
-->
</tx:attributes>
</tx:advice>
<!-- 配置哪些类的方法进行事务管理 -->
<aop:config>
<aop:pointcut id="allManagerMethod" expression="execution (* com.bjsxt.oa.managers.*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="allManagerMethod"/>
</aop:config>
二是用事务拦截器的方式来控制事务:
<!-- Transaction manager for a single Hibernate SessionFactory (alternative to JTA) -->
<bean id="myTransactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory">
<ref local="mySessionFactory" />
</property>
</bean>
<!-- 配置事务管理 -->
<bean id="userService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager">
<ref local="myTransactionManager" />
</property>
<property name="target">
<ref local="loginTarget" />
</property>
<property name="transactionAttributes">
<props>
<prop key="save*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<!-- OrderTarget primary business object implementation -->
<bean id="loginTarget" class="com.test.spring.UserServiceImpl">
<property name="userDAOIF">
<ref local="userDAO" />
</property>
</bean>
<!-- DAO object: Hibernate implementation -->
<bean id="userDAO" class="com.test.hibernate.UserDAOImpl">
<property name="sessionFactory">
<ref local="mySessionFactory" />
</property>
</bean>