前言
本篇紧接着spring入门详细教程(三),建议阅读本篇前,先阅读第一篇,第二篇以及第三篇。链接如下:
Spring入门详细教程(一) https://www.cnblogs.com/jichi/p/10165538.html
Spring入门详细教程(二) https://www.cnblogs.com/jichi/p/10176601.html
Spring入门详细教程(三) https://www.cnblogs.com/jichi/p/10177004.html
Spring入门详细教程(四) https://www.cnblogs.com/jichi/p/10211475.html
本篇主要讲解spring的事务处理。
一、什么是事务
事务用白话来说比较好理解,我们举个例子。比如说你做两件事要达成一个目的。其中有一件事失败,你就相当于没做。如果两件事都成功,这件事你才算做的成功。用官方话来解释,就是事务是逻辑上的一组操作,组成这组操作的各个逻辑单元,要么一起成功,要么一起失败。
二、事务的特性
了解了事务的概念,我们就可以了解事务的特性了。
事务有四大特性:原子性,一致性,隔离性,持久性。
原子性:强调事务的不可分割。
一致性:事务的执行的前后数据的完整性保持一致。
隔离性:一个事务执行的过程中,不应受到其他事务的干扰。
持久性:事务一旦结束,数据就持久到数据库。
三、事务的并发问题
事务三大问题,脏读,幻读,不可重复读。
脏读:一个事务读到了另一个事务的未提交的数据。
不可重复读:一个事务读到了另一个事务已经提交的update的数据导致多次查询结果不一致。
虚幻读:一个事务读到了另一个事务已经提交的insert的数据导致多次查询结果不一致。
四、事务并发问题的解决:事务隔离级别
1、未提交读:脏读,不可重复读,虚幻读都有可能发生。
2、已提交读:避免脏读。不可重复读和虚幻读都可能发生。
3、可重复读:避免脏读和不可重复读。虚幻读可能发生。
4、串行化:避免以上所有的读问题。
事务的隔离级别越高,性能会降的越低。其实就是牺牲性能来提高准确性。在实际中,一般选取中间的隔离级别。
MysqL默认隔离级别:可重复读。
oracle默认隔离级别:已提交读。
五、spring封装事务
首先spring封装了我们需要进行的事务操作。事务操作是什么呢。比如说我们首先需要打开事务,进行操作后,提交事务。如果发生错误,回滚事务,如果中途未发生错误,则事务进行提交。如果spring没有对事务进行封装,我们需要没进行一次操作都重新写事务的处理代码。spring封装后,事务代码被封装,我们不用一遍遍的重复编写代码,配置好后,不用书写事务代码。接下来我们了解几个spring中事务的相关概念。
1、PlatformTransactionManager平台事务管理器
在不同的平台,操作代码的事务各不相同,spring为我们提供了一个接口。这个接口就是PlatformTransactionManager。
我们可以看一下里面的源码。提供了一个获得事务的方法,一个提交事务的方法以及一个回滚事务的方法。此处贴一下源码
@H_404_124@/* * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License,Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing,software * distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.transaction; /** * This is the central interface in Spring's transaction infrastructure. * Applications can use this directly,but it is not primarily meant as API: * Typically,applications will work with either TransactionTemplate or * declarative transaction demarcation through AOP. * * <p>For implementors,it is recommended to derive from the provided * {@link org.springframework.transaction.support.AbstractPlatformTransactionManager} * class,which pre-implements the defined propagation behavior and takes care * of transaction synchronization handling. Subclasses have to implement * template methods for specific states of the underlying transaction,* for example: begin,suspend,resume,commit. * * <p>The default implementations of this strategy interface are * { org.springframework.transaction.jta.JtaTransactionManager} and * { org.springframework.jdbc.datasource.DataSourceTransactionManager},* which can serve as an implementation guide for other transaction strategies. * * @author Rod Johnson * Juergen Hoeller * @since 16.05.2003 * @see org.springframework.transaction.support.TransactionTemplate * org.springframework.transaction.interceptor.TransactionInterceptor * org.springframework.transaction.interceptor.TransactionProxyfactorybean */ public interface PlatformTransactionManager { * Return a currently active transaction or create a new one,according to * the specified propagation behavior. * <p>Note that parameters like isolation level or timeout will only be applied * to new transactions,and thus be ignored when participating in active ones. * <p>Furthermore,not all transaction definition settings will be supported * by every transaction manager: A proper transaction manager implementation * should throw an exception when unsupported settings are encountered. * <p>An exception to the above rule is the read-only flag,which should be * ignored if no explicit read-only mode is supported. Essentially,the * read-only flag is just a hint for potential optimization. * @param definition TransactionDefinition instance (can be {@code null} for defaults),* describing propagation behavior,isolation level,timeout etc. * @return transaction status object representing the new or current transaction * @throws TransactionException in case of lookup,creation,or system errors * IllegalTransactionStateException if the given transaction definition * cannot be executed (for example,if a currently active transaction is in * conflict with the specified propagation behavior) * TransactionDefinition#getPropagationBehavior * TransactionDefinition#getIsolationLevel * TransactionDefinition#getTimeout * TransactionDefinition#isReadOnly */ TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException; * Commit the given transaction,with regard to its status. If the transaction * has been marked rollback-only programmatically,perform a rollback. * <p>If the transaction wasn't a new one,omit the commit for proper * participation in the surrounding transaction. If a prevIoUs transaction * has been suspended to be able to create a new one,resume the prevIoUs * transaction after committing the new one. * <p>Note that when the commit call completes,no matter if normally or * throwing an exception,the transaction must be fully completed and * cleaned up. No rollback call should be expected in such a case. * <p>If this method throws an exception other than a TransactionException,* then some before-commit error caused the commit attempt to fail. For * example,an O/R Mapping tool might have tried to flush changes to the * database right before commit,with the resulting DataAccessException * causing the transaction to fail. The original exception will be * propagated to the caller of this commit method in such a case. * status object returned by the { getTransaction} method * UnexpectedRollbackException in case of an unexpected rollback * that the transaction coordinator initiated * HeuristicCompletionException in case of a transaction failure * caused by a heuristic decision on the side of the transaction coordinator * TransactionSystemException in case of commit or system errors * (typically caused by fundamental resource failures) * IllegalTransactionStateException if the given transaction * is already completed (that is,committed or rolled back) * TransactionStatus#setRollbackOnly */ void commit(TransactionStatus status) * Perform a rollback of the given transaction. * <p>If the transaction wasn't a new one,just set it rollback-only for proper * participation in the surrounding transaction. If a prevIoUs transaction * has been suspended to be able to create a new one,resume the prevIoUs * transaction after rolling back the new one. * <p><b>Do not call rollback on a transaction if commit threw an exception.</b> * The transaction will already have been completed and cleaned up when commit * returns,even in case of a commit exception. Consequently,a rollback call * after commit failure will lead to an IllegalTransactionStateException. * TransactionSystemException in case of rollback or system errors * (typically caused by fundamental resource failures) * void rollback(TransactionStatus status) TransactionException; }