分布式事务第一弹——认识本地事务

118 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第12天,点击查看活动详情

每日英语:

The rest of the world may follow the rules,but I must follow my heart.

翻译:其他人可能会循规蹈矩,但我必须遵循自己的内心。 ——《寻梦环游记》

分布式事务

在分布式系统中,为了保证数据的高可用,通常,我们会将数据保留多个副本(replica),这些副本会放置在不同的物理的机器上。为了对用户提供正确的 CRUD 等语义,我们需要保证这些放置在不同物理机器上的副本是一致的。分布式事务在现在遍地都是分布式部署的系统中几乎是必要的。

事务简介

事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。在关系数据库中,一个事务由一组SQL语句组成。事务应该具有4个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为ACID特性。

原子性(atomicity) :事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。

一致性(consistency) :事务必须是使数据库从一个一致性状态变到另一个一致性状态,事务的中间状态不能被观察到的。

隔离性(isolation) :一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。隔离性又分为四个级别:读未提交(read uncommitted)、读已提交(read committed,解决脏读)、可重复读(repeatable read,解决虚读)、串行化(serializable,解决幻读)。

持久性(durability) :持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。

任何事务机制在实现时,都应该考虑事务的ACID特性,包括:本地事务、分布式事务,即使不能都很好的满足,也要考虑支持到什么程度。

本地事务

大多数场景下,我们的应用都只需要操作单一的数据库,这种情况下的事务称之为本地事务(Local Transaction)。本地事务的ACID特性是数据库直接提供支持。本地事务应用架构如下所示:

1605222052090.png

很多java应用都整合了spring,并使用其声明式事务管理功能来完成事务功能。一般使用的步骤如下:

1、配置事务管理器。spring提供了一个PlatformTransactionManager接口,其有2个重要的实现类:

DataSourceTransactionManager:用于支持本地事务,事实上,其内部也是通过操作java.sql.Connection来开启、提交和回滚事务。

JtaTransactionManager:用于支持分布式事务,其实现了JTA规范,使用XA协议进行两阶段提交。需要注意的是,这只是一个代理,我们需要为其提供一个JTA provider,一般是Java EE容器提供的事务协调器(Java EE server's transaction coordinator),也可以不依赖容器,配置一个本地的JTA provider。

2、 在需要开启的事务的bean的方法上添加@Transitional注解

总结

本篇主要介绍了一下本地事务,可以看到spring除了支持本地事务,也支持分布式事务,下一篇我们先对分布式事务的典型应用场景进行介绍。