事务的基本概念
事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。
特点:事务是恢复和并发控制的基本单位。事务应该具有4个属性:原子性、_致性、 隔离性、持久性。这四个属性通常称为ACID特性。
原子性(Automicity ) o 一个事务是一个不可分割的工作单位,事务中包括的诸操作要 么都做,要么都不做。
一致性(Consistency )o事务必须是使数据库从一个一致性状态变到另一个一致性状态。 一致性与原子性是密切相关的。
隔离性(Isolation )。一个事务的执行不能被其他事务干扰。即一个事务内部的操作及 使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
持久性(Durability几持久性也称永久性(Permanence ),指一个事务一旦提交,它 对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对具有任何 影响。
事务的基本原理
Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无 法提供事务功能的。对于纯JDBC操作数据库,想要用到事务,可以按照以下步骤进行:
- 获取连接 Connection con = DriverManager.getConnection()
- 开启事务con.setAutoCommit(true/false);
- 执行CRUD
- 提交事务/回滚事务 con.commit() / con.rollback。;
- 关闭连接con.close()
使用Spring的事务管理功能后 我们可以不再写步骤2和4的代码 而是由Spirng自
动完成。 那么Spring是如何在我们书写的CRUD之前和之后开启事务和关闭事务的
呢?解决这个问题,也就可以从整体上理解Spring的事务管理实现原理了。下面简单地
介绍下,注解方式为例子
配置文件开启注解驱动,在相关的类和方法上通过注解@而1^(:而曲标识。
Spring在启动的时候会去解析生成相关的bean ,这时候会查看拥有相关注解的类和方
法,并且为这些类和方法生成代理,并根据©Transaction的相关参数进行相关配置注入,
这样就在代理中为我们把相关的事务处凰卓了(开启正常提交事务,异常回滚事务)O
真正的数据库层的事务提交和回滚是通过binlog或者redo log实现的。
Spring事务的传播属性
所谓spring事务的传播属性,就是定义在存在多个事务同时存在的时候r spring应该如 何处理这些事务的行为。这些属性在TransactionDefinition中定义,具体常量的解释见 下表:
常量名称 | 常量解释 |
---|---|
PROPAGATION_REQUIRED | 支持当前事务,如果当前没有事务,就新建 一个事务。这是最常见的选择,也是Spring 默认的事务的传播。 |
PROPAGATION_REQUIRES_NEW | 新建事务,如果当刖存在事务,把当刖事务 挂起。新建的事务将和被挂起的事务没有任 何关系,是两个独立的事务,外层事务失败 回滚之后,不能回滚内层事务执行的结果, 内层事务失败抛出异常,外层事务捕获,也 可以不处理回滚操作 |
PRO PAGATION_SUPPO RTS | 支持当前事务,如果当前没有事务,就以非 事务方式执行。 |
PRO PAGATION_MAN DATO RY | 支持当前事务,如果当前没有事务,就抛出 异常。 |
PROPAGATION_NOT_SUPPORTED | 以非事务方式执行操作,如果当刖存在事 务,就把当前事务挂起。 |
PROPAGATION_NEVER | 以非事务方式执行,如果当前存在事务,则 抛出异常。 |
PROPAGATION_NESTED | 如果一个活动的事务存在,则运行在一个嵌 套的事务中。如果没有活动事务,则按REQUIRED属性执行。它使用了一个单独的 事务,这个事务拥有多个可以回滚的保存 点。内部事务的回滾不会对外部事务造成影 响。它只对DataSourceTransactionManager 事务管 理器起效。 |
数据库隔离级别
隔离级别 | 隔离级别的值 | 导致的问题 |
---|---|---|
Read-Uncommitted | 0 | 导致脏读 |
Read-Committed | 1 | 避免脏读,允许不可重复读和幻读 |
Repeatable-Read | 2 | 避免脏读,不可重复读,允许幻读 |
Serializable | 3 | 串行化读,事务只能一个一个执行,避免了 脏读、不可重复读、幻读。执行效率慢,使 用时慎重 |
脏读:一事务对数据进行了增删改,但未提交,另一事务可以读取到未提交的数据。如 果第一个事务这时候回滚了,那么第二个事务就读到了脏数据。
不可重复读:一个事务中发生了两次读操作,第一次读操作和第二次操作之间,另外一 个事务对数据进行了修改,这时候两次读取的数据是不一致的。
幻读:第一个事务对一定范围的数据进行批量修改,第二个事务在这个范围增加一条数 据,这时候第一个事务就会丢失对新增数据的修改。
总结:
隔离级别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大。
大多数的数据库默认隔离级别为Read-Commited ,比如SqlServer. Oracle;
少数数据库默认隔离级别为:Repeatable-Read比如:MySQL InnoDB;