Spring 事务控制
spring的事务概念
事务的四大特征
原⼦性(Atomicity) :共⽣死,要么全部成功,要么全部失败!
⼀致性(Consistency):事务在执⾏前后,数据库中数据要保持⼀致性状态。
隔离性(Isolation):事务与事务之间的执⾏应当是相互隔离互不影响的。
1.READ_UNCOMMITTED (读未提交)隔离级别最低的⼀种事务级别。在这种隔离级别下,会引发脏读、不可重复读和幻读。
2.READ_COMMITTED (读已提交)读到的都是别⼈提交后的值。这种隔离级别下,会引发不可重复读和幻读,但避免了脏读。
3.REPEATABLE_READ (可重复读)这种隔离级别下,会引发幻读,但避免了脏读、不可重复读。
4.SERIALIZABLE (串⾏化)最严格的隔离级别。在Serializable隔离级别下,所有事务按照次序依次执⾏。脏读、不可重复读、幻读都不会出现。
**持久性(Durability)**事务提交完毕后,数据库中的数据的改变是永久的。
Spring 事务核⼼接⼝
Spring 事务管理器的接⼝是org.springframework.transaction.PlatformTransactionManager,通
过这个接⼝,Spring 为各个平台如 JDBC、Hibernate 等都提供了对应的事务管理器,但是具体的实现
就是各个平台⾃⼰的事情了。此接⼝的内容如下:
public interface PlatformTransactionManager(){
// 由 TransactionDefinition 得到 TransactionStatus 对象
TransactionStatus getTransaction(TransactionDefinition definition) throws
TransactionException;
// 提交
void commit(TransactionStatus status) throws TransactionException;
// 回滚
void rollback(TransactionStatus status) throws TransactionException;
}
Spring 事务控制配置
XML 配置
添加命名空间; 设置aop代理; 配置事务管理器; 配置事务相关通知; 配置aop
事务传播⾏为介绍:
@Transactional(propagation=Propagation.REQUIRED)
如果有事务, 那么加⼊事务, 没有的话新建⼀个(默认情况下)
@Transactional(propagation=Propagation.NOT_SUPPORTED)
容器不为这个⽅法开启事务
@Transactional(propagation=Propagation.REQUIRES_NEW)
不管是否存在事务,都创建⼀个新的事务,原来的挂起,新的执⾏完毕,继续执⾏⽼的事务
@Transactional(propagation=Propagation.MANDATORY)
必须在⼀个已有的事务中执⾏,否则抛出异常
@Transactional(propagation=Propagation.NEVER)
必须在⼀个没有的事务中执⾏,否则抛出异常(与 Propagation.MANDATORY 相反)
@Transactional(propagation=Propagation.SUPPORTS)
如果其他 bean 调⽤这个⽅法,在其他 bean 中声明事务,那就⽤事务.
如果其他 bean 没有声明事务,那就不⽤事务.
@Transactional(propagation=Propagation.NESTED)
⽀持当前事务,如果当前事务存在,则执⾏⼀个嵌套事务,如果当前没有事务,就新建⼀个事务。
注解配置
1> 配置事务管理器
<!-- spring 注解式事务声明 -->
<!-- 事务管理器定义 -->
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
2> 配置注解⽀持
<tx:annotation-driven transaction-manager="txManager"/>
3>⽅法上加⼊事务注解
@Override
@Transactional(propagation=Propagation.REQUIRED)
public void saveUser(String userName,String userPwd){
User user1=new User();
user1.setUserName(userName);
user1.setUserPwd(userPwd);
userDao.saveUser(user1);
userDao.delUserById(2);
}
备注:默认 spring 事务只在发⽣未被捕获的 runtimeexcetpion 时才回滚。
spring aop 异常捕获原理:
被拦截的⽅法需显式抛出异常,并不能经任何处理,这样aop 代理才能捕获到⽅法的异常,才能进⾏回
滚,默认情况下 aop 只捕获 runtimeexception 的异常,但可以通过配置来捕获特定的异常并回滚换
句话说在 service 的⽅法中不使⽤ try catch 或者在 catch 中最后加上 throw new
RunTimeexcetpion(),这样程序异常时才能被 aop 捕获进⽽回滚.