事务定义:
是一组单一逻辑工作单元的操作集合,要么全部执行,要么不执行。典型的应用是银行转账业务。
事务四大特性:
1. 原子性:事务中全部操作在数据库中是不可分割的,要么全部执行,要么不执行
2. 一致性:几个并行执行的事务,其执行结果必须按某一顺序执行的结果相一致
3. 隔离性: 事务执行不受到其他事务的干扰
4. 持久性:对于事务进行提交后,系统必须保证数据库改变不丢失,即使出现故障
注意:事务如果不考虑隔离性,会引发安全问题:脏读、不可重复读、幻读
脏读:一个事物读取了另一个事务改写的但未提交的数据,如果这些数据被回滚,则读到的数据是无效的
不可重复读: 在同一个事务中,多次读取同一数据返回的结果有所不同
幻读: 一个事物读取几行记录后,另一个事务插入一些记录,幻读就发生了。再后来进行查询,第一个事物就会发现有些原来没有的记录。
事物隔离级别
Default : 使用后端数据库默认的隔离级别(Spring中可以进行选择)
Read_uncommited 允许你读取还未提交的改变的数据。导致脏读、幻读、不可重复度
Read_commited 允许在并发事物已经提交后读取。防止脏读,但幻读、不可重复读仍会发生
Repeatable_read 对相同字段多次读取是一致的,除非数据北十五本身改变。可防止脏读、不可重复读,但幻读仍会发生
Serializable 完全服从ACID隔离级别,确保不发生脏、幻、不可重复度。执行效率最慢,它是典型的通过完全锁定在食物中涉及的数据表来完成的。
Spring事务传播属性
Propagation : key属性确定代理应该给哪个方法增加事务行为。这样的属性最重要的部份是传播行为。有以下选项可供使用:
PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。
Spring中事务管理应用
(一)编程式事务管理(TransactionTempletate)
使用TransactionTemplate
applicationContext.Xml文件中配置事务管理器
//配置事务管理器
<bean id="transactionManager" class="org.springframework.jdbc.datasource.dataSourceTransactionManager ">
<property name="dataSource" ref=" dataSource "></property>
</bean>
//配置事务管理模板:Spring为简化事务管理代码提供的类
<bean id="txTemplate" class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager" ref="transactionManager"></property>
<property name="propagationBehaviorName" value="PROPAGATION_REQUIRED"></property> //可在这里定义传播行为和隔离级别
</bean>
Service 层代码
publicclass Temp1Service {
private UserDAO userDAO;
private DeptDAO deptDAO;
TransactionTemplate txTemplate;
Get..()/Set..()
publicvoid addTemp(){
txTemplate.execute(new TransactionCallback(){
public Object doInTransaction(TransactionStatus status){
try {
User user = new User();
Dept dept = new Dept();
user.setRemark("USER REMARK");
dept.setRemark("DEPT REMARK");
userDAO.save(user);
deptDAO.save(dept);
} catch (Exception e) {
status.setRollbackOnly();//
e.printStackTrace();
returnfalse;
}
returntrue;
}
});
}
}
(二)声明式事务管理
1. 声明式事务管理方式一:基于TransactionProxyFactoryBean的方式
这里主要是用到业务层代理
在applicationContext.Xml文件中配置
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 配置TransactionManager时需要注入数据源引用 -->
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 下面这个是前面定义的业务Bean -->
<bean id="newsDao" class="com.abc.dao.impl.NewsDaoImpl">
<!-- 为业务Bean注入属性 -->
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="newsDaoTransProxy"
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<!-- 为事务代理工厂Bean注入事务管理器 -->
<property name="transactionManager" ref="transactionManager" />
<!-- 要在哪个Bean上面创建事务代理对象 -->
<property name="target" ref="newsDao" />
<!-- 指定事务属性 包括传播行为和隔离级别-->
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
2. 声明式事务管理方式二:基于AspectJ的XML方式
<!-- 切面 -->
<bean id="myAspect" class="net.csdn.www.aop.MyAspect"></bean>
<bean id="userDao" class="net.csdn.www.dao.UserDao"></bean>
<!-- 切入点 -->
<aop:config>
<aop:aspect id="asp1" ref="myAspect">
<aop:before method="authority" pointcut="execution(* net.csdn.www.dao.*.*(..))" />
<aop:after method="release" pointcut="execution(* net.csdn.www.dao.*.*(..))" />
<aop:after-returning method="log"
pointcut="execution(* net.csdn.www.dao.*.*(..))" returning="rvt" />
<aop:around method="processTx" pointcut="execution(* net.csdn.www.dao.*.*(..))" />
</aop:aspect>
</aop:config>
3. 声明式事务管理方式三:基于注解的方式
applicationContext.xml文件中
<beans
@Transactional
@Component("userDao")
public
参考http://www.blogjava.net/robbie/archive/2009/04/05/264003.html