事务就是一组数据库操做,但这组操做是具备原子性的(atomic)。所谓原子操做,即这组数据库操做要么就都执行成功,要么就一个也没执行。当有一些操做成功了(“成功”指数据库里的数据已更新或提交),但中间出现异常,后边的也就没法执行时,事务要回滚,即恢复到什么也没执行之前的状态。spring
举个比较常见的例子,一位顾客要进行银行转账,把100元从A账户转到B账户,通常的过程是把A账户的总额减去100,B账户的总额加上100(只考虑最简单状况)。当在A账户总额减去100后出现异常状况,使得没法再对B账户进行操做。若是没使用事务,那么这位顾客就损失了100元,但若是使用了事务,那么出现异常后,事务回滚,使得A账户总额恢复到减去100之前的金额。虽然使用事务并无达到顾客转账的目的,但避免了出现异常状况时顾客的损失。数据库
事务就至关于咱们作一件事情(这件事由许多小的步骤组成),要么咱们就把这件事情完完整整地作成功,要么咱们就一点也不要作。不能作到半截撂摊子不干了。 |
回到Spring来,Spring的Dao框架对事务提供了强大的支持。它包括有两种事物管理,即:编程
编程式事物管理(programmatic tansaction management)框架
声明式事物管理(Declarative tansaction management)优化
所谓编程式事物管理,就是把事物管理以代码的形式编写到你的应用中要使用事物管理的地方,灵活性较强。而声明式事物管理是以配置文件的形式在xml文件中定义,好处是不具备代码入侵性,当不须要事物管理时,能够直接修改配置文件,而不用修改代码。之后会介绍这两种事物管理。atom
在Spring中,主要涉及如下几种事物属性:spa
1. 传播行为(propagation behavior)xml
它是对事物的起始,暂停,终止时刻的定义,主要有如下几种接口
参数 | 含义 |
PROPAGATION_REQUIRED | 若是存在事物的话,就继续这个事物,若是不存在,新建一个事物。 |
PROPAGATION_SUPPORTS | 若是存在事物的话,就继续这个事物,若是不存在,就以非事务的方式进行。 |
PROPAGATION_MANDATORY | 必须在现存事物中执行,不然抛出异常。 |
PROPAGATION_REQUIRES_NEW | 创建一个新事物,若是现存一个事物,则暂停它。 |
PROPAGATION_NOT_SUPPORTED | 再也不事务中执行,若是现存事物,则暂停它。 |
PROPAGATION_NEVER | 再也不事务中执行,若是现存事物,则抛出异常。 |
PROPAGATION_NESTED | 在一个嵌入的事物中执行,不然同PROPAGATION_REQUIRED |
上述参数是在org.springframework.transaction.TransactionDefinition接口中定义的(类型是public static final,值从0到6)。上述参数中最经常使用的是PROPAGATION_REQUIRED。事务
2. 隔离等级(isolation level)
在一个应用应用程序中,可能有多个事务在运行,这时就会产生一些问题。
dirty read
一个事物更新了数据库中的某些数据,另外一个事物读取了这些数据,这时前一个事物因为某些缘由回滚了,那么第二个事物读取的数据就是“脏数据”。
non-repeatable read
一个事物须要两次查询同一数据,但两次查询中间可能有另一个事物更改了这个数据,致使前一个事物两次读出的数据不一致。
phantom read
一个事物两次查询同一个表,但两次查询中间可能有另一个事物又向这个表中插入了一些新数据,致使前一个事物的两次查询不一致。
为了解决以上问题,Spring的事物管理定义了一些隔离级别,所谓“隔离”,即对数据的锁定。
参数 | 含义 |
ISOLATION_DEFAULT | 使用数据库默认的隔离级别 |
ISOLATION_READ_UNCOMMITTED | 允许事物读取其余并行事物还未提交的数据。这种级别会出现上面三种状况。 |
ISOLATION_READ_COMMITTED | 允许事物读取其余并行事物已经提交(commit)的数据,可防止dirty read |
ISOLATION_REPEATABLE_READ | 这种级别会能够防止上面三种状况发生。 |
ISOLATION_SERIALIZABLE | 使用事物锁,锁定相应数据,能够防止上面三种状况发生,但效率比较低。 |
上述参数也是在org.springframework.transaction.TransactionDefinition接口中定义的(类型是public static final,值为-1,1,2,4,8)。上述参数中最经常使用的是ISOLATION_DEFAULT。
3. read only
应用这项属性时,底层的数据库能够对读取进行最优化,但要配合PROPAGATION_REQUIRED,PROPAGATION_REQUIRES_NEW或PROPAGATION_NESTED使用,即只能在事物中使用。
4. timeout
在多事物并行状况下,为了保证正确性,有些事物的操做会有延迟,甚至死锁。设置事物超时时间,能够避免事物的长时间等待。设置事物超时时间也要配合PROPAGATION_REQUIRED,PROPAGATION_REQUIRES_NEW或PROPAGATION_NESTED使用。
以上的四种属性及其相应方法都定义在org.springframework.transaction.TransactionDefinition接口及其实现类(如org.springframework.transaction.support.DefaultTransactionDefinition)里。