概念
事物就是一系列的动作,它们被当做一个单独的工作单元,这些动作要么全部完成,要么全部不起作用。用来确保数据的完整性和一致性。
事物的四个关键属性(ACID)
- 原子性:一个事务要被完全的无二义性的做完或撤消。在任何操作出现一个错误的情况下,构成事务的所有操作的效果必须被撤消,数据应被回滚到以前的状态。
- 一致性:一个事务应该保护所有定义在数据上的不变的属性(例如完整性约束)。在完成了一个成功的事务时,数据应处于一致的状态。换句话说,一个事务应该把系统从一个一致-状态转换到另一个一致状态。举个例子,在关系数据库的情况下,
一个一致的事务将保护定义在数据上的所有完整性约束。 - 隔离性:在同一个环境中可能有多个事务并发执行,而每个事务都应表现为独立执行。串行的执行一系列事务的效果应该同于并发的执行它们。这要求两件事:
在一个事务执行过程中,数据的中间的(可能不一致)状态不应该被暴露给所有的其他事务。
两个并发的事务应该不能操作同一项数据。数据库管理系统通常使用锁来实现这个特征。 - 持久性:个被完成的事务的效果应该是持久的。
Spring事物管理
spring提供的事务管理可以分为两类:编程式的和声明式的。编程式就是用注解的方式写到代码里;声明式就是在Spring的配置文件中进行相关配置。
Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource、TransactionManager和代理机制这三部分,无论哪种配置方式,一般变化的只是代理机制这部分。 DataSource、 TransactionManager这两部分只是会根据数据访问方式有所变化,比如使用Hibernate进行数据访问时,DataSource实际为 SessionFactory,TransactionManager的实现为HibernateTransactionManager。
使用spring编程式配置事物
- 1、配置事物管理器
<!-- 配置sessionFactory -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="configLocation">
<value>classpath:config/hibernate.cfg.xml</value>
</property>
<property name="packagesToScan">
<list>
<value>com.entity</value>
</list>
</property>
</bean>
<!-- 配置事务管理器(声明式的事务)hibernate -->
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>
<property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
</bean>
<!-- 配置事务管理器(声明式的事务) -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DatasourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
- 2、启用事物注解
<tx:annotation-driven transanction-manager="transactionManager">
- 3、添加事物注解
在对应的方法上添加注解@Tranctional
package com.dao;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.entity.User;
@Transactional
public class UserDaoImpl_BAK extends HibernateTemplate {
@Transactional(propagation=Propagation.REQUIRED,rollbackForClassName="Exception")
public void addUser(User user) throws Exception {
this.save(user);
}
@Transactional(propagation=Propagation.REQUIRED,rollbackForClassName="Exception")
public void modifyUser(User user) {
this.update(user);
}
@Transactional(propagation=Propagation.REQUIRED,rollbackForClassName="Exception")
public void delUser(String username) {
this.delete(this.load(User.class, username));
}
@Transactional(readOnly=true)
public void selectUser() {
}
}
类头的@Transactional为默认事务配置,如方法没有自己的事务类型,则按默认事务,如有自己的配置,则按自己的配置。
声明式配置-常用的两种
- 1、使用tx标签方式
<tx:advice id="txadvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" propagation="REQUIRED" isolation="READ_COMMITTED" rollback-for="Exception" />
<tx:method name="modify*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="del*" propagation="REQUIRED" rollback-for="Exception" />
<tx:method name="*" propagation="REQUIRED" read-only="true" />
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="pointcut1" expression="execution(* com.np.dao.*.*(..))"></aop:pointcut>
<aop:advisor advice-ref="txadvice" pointcut-ref="pointcut1"></aop:advisor>
</aop:config>
< tx:advice >:事物通知定义,用于指定事物属性,transaction-manager用于指定事物管理器,< tx:attributes >用于指定具体需要拦截的方法name=”add*”表示将拦截以add开头的方法,propagation用于指定事物传播类型,isolation指定事物隔离级别。
< aop:pointcut >切入点定义。
- 2、使用代理方式
<!-- 第二种配置事务的方式 ,代理-->
<bean id="transactionProxy"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true">
<property name="transactionManager" ref="transactionManager"></property>
<property name="transactionAttributes">
<props>
<prop key="add*">PROPAGATION_REQUIRED, -Exception</prop>
<prop key="modify*">PROPAGATION_REQUIRED, -Exception</prop>
<prop key="del*">PROPAGATION_REQUIRED, -Exception</prop>
<prop key="*">PROPAGATION_REQUIRED, readOnly</prop>
</props>
</property>
</bean>
<bean id="userDao" parent="transactionProxy">
<property name="target">
<!-- 用bean代替ref的方式-->
<bean class="com.dao.UserDaoImpl">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
</property>
</bean>
- 3、spring事物传播类型
propagation | 解释 |
---|---|
REQUIRED | 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择 |
REQUIRES_NEW | 新建事务,如果当前存在事务,把当前事务挂起 |
SUPPORTS | 支持当前事务,如果当前没有事务,就以非事务方式执行 |
MANDATORY | 支持当前事务,如果当前没有事务,就抛出异常 |
NOT_SUPPORTED | 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起 |
NEVER | 以非事务方式执行,如果当前存在事务,则抛出异常 |
NESTED | 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与REQUIRED类似的操作。 |