Spring事务总结

文章目录

  • 事务分类
  • 本地事务
    • 事务原理
    • 事务隔离级别
    • 事务的传播属性

事务分类

数据库分为本地事务和分布式事务
a. 本地事务: 涉及一个数据库,能保证在该数据库操作上的ACID
b. 分布式事务: 涉及多个数据库的事务(由每个数据库的本地事务组成),目的保证多个数据库的数据一致性。

Java事务分为JDBC事务和JTA事务
a. JDBC事务: 完成数据库事务中的本地事务,通过connection对象控制。
b. JTA事务: JTA(Java Transaction API), 是J2EE数据库事务规范,JTA只提供了事务管理接口,由应用程序服务器厂商提供实现,JTA事务比JDBC更强大,支持分布式事务。

本地事务

事务原理

Spring事务的本质其实就是数据库对事务的支持,基本步骤如下:

1 获取连接 Connection con = DriverManager.getConnection()
2 开启事务 con.setAutoCommit(true/false);
3 执行CRUD
4 提交事务/回滚事务 con.commit()/con.rollback();
5 关闭连接 conn.close();

事务隔离级别

Spring 事务依靠mysql实现,因此Spring事务隔离级别和Mysql事务隔离级别一致。但在Spring事务中存在一个默认的隔离级别,用于使用数据库中默认的隔离级别。

常量 解释
ISOLATION_DEFAULT 这是个 PlatfromTransactionManager 默认的隔离级别,使用数据库默认的事务隔离级别。另外四个与 JDBC 的隔离级别相对应。
ISOLATION_READ_UNCOMMITTED 这是事务最低的隔离级别,它充许另外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。
ISOLATION_READ_COMMITTED 保证一个事务修改的数据提交后才能被另外一个事务读取。存在不可重复现象
ISOLATION_REPEATABLE_READ 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。
ISOLATION_SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。

事务的传播属性

所谓Spring事务的传播属性,就是定义在存在多个事务同时存在的时候,spring应用如何处理这些事务的行为。在TransactionDefinition中定义,具体常量的解释见下表:

常量名称 常量解释
PROPAGATION_REQUIRED 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择,也是 Spring 默认的事务的传播。
PROPAGATION_REQUIRES_NEW 新建事务,如果当前存在事务,把当前事务挂起。新建的事务将和被挂起的事务没有任何关系,是两个独立的事务,外层事务失败回滚之后,不能回滚内层事务执行的结果,内层事务失败抛出异常,外层事务捕获,也可以不处理回滚操作
PROPAGATION_SUPPORTS 支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY 支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER 以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED 如果一个活动的事务存在,则运行在一个嵌套的事务中。如果没有活动事务,则按REQUIRED属性执行。它使用了一个单独的事务,这个事务拥有多个可以回滚的保存点。内部事务的回滚不会对外部事务造成影响。它只对DataSourceTransactionManager事务管理器起效。

REQUIRES_NEW 和 NESTED 区别
PROPAGATION_REQUIRES_NEW 启动一个新的, 不依赖于环境的 “内部” 事务. 这个事务将被完全 commited 或 rolled back 而不依赖于外部事务, 它拥有自己的隔离范围, 自己的锁, 等等. 当内部事务开始执行时, 外部事务将被挂起, 内务事务结束时, 外部事务将继续执行.

另一方面, PROPAGATION_NESTED 开始一个 “嵌套的” 事务, 它是已经存在事务的一个真正的子事务. 潜套事务开始执行时, 它将取得一个 savepoint. 如果这个嵌套事务失败, 我们将回滚到此 savepoint. 潜套事务是外部事务的一部分, 只有外部事务结束后它才会被提交.

由此可见, PROPAGATION_REQUIRES_NEW 和 PROPAGATION_NESTED 的最大区别在于, PROPAGATION_REQUIRES_NEW 完全是一个新的事务, 而 PROPAGATION_NESTED 则是外部事务的子事务, 如果外部事务 commit, 潜套事务也会被 commit, 这个规则同样适用于 roll back.

你可能感兴趣的:(Spring,javaEE)