一个逻辑单元执行的一组操作,要么全成功,要么全失败。
事务包括四大特性:ACID
原子性:事务必须是最小的工作单元,不可再分。要么全成功,要么全失败。事务执行过程中失败,会回滚到之前的状态。
一个事务的执行前后,数据库从一个一致性状态编程另外一个一致性状态。简单来说,A和B一共100元,无论怎么分配钱,加起来一定是100元。保证了一致性。
相当于事务所有操作要么都成功,要么都失败。
通过日志文件回滚保证数据的一致性。
多个事务同时访问一个数据,要有次序,当一个事务操作时候,其他事务不能干扰,相互隔离。
当事务结束后,数据的改变是永久性的。
事务有四个隔离级别:读未提交,读已提交,可重复读,序列化读/串行读。而在数据操作中,当多个事务访问同一个数据可能出现多种问题:脏读,不可重复读,幻象的情况。
事务A和事务B同时访问一组数据,当事务对数据进行操作,但是没有提交,此时事务B却可以查询到更新后的数据。
问题:脏读,可以查询未提交事务的数据。 解决办法:读已提交。
事务A和B同时访问一组数据,事务A对数据进行操作,如果不提交,事务B只能读到老数据。只有事务A提交的时候,事务B才能读到新数据。
问题:不可重复读,事务A提交前后,事务B查询到的数据不一致。 解决办法:可重复读。
这是MySQL默认的隔离级别。
事务A和B同时访问一组数据,事务A对数据进行操作,提交事务。只要事务B不结束,事务B无论啥时候查询到都是老数据,没有更新。
问题:幻象,独到的数据是假的。 解决方法:序列化读/串行读。
事务A和B同时访问一组数据,事务A对数据进行操作,且不提交事务,此时事务B对数据的SQL语句无法执行,只有当事务A提交事务,事务B的SQL才能执行,并且是最新数据。
缺点:需要排队。优点:保证了数据的有效性,合法性。
隔离级别越高,越能保证数据的完整性和一致性。但是对并发性能有影响,对于大部分情况,能够避免脏读,不可重复读的情况。对于幻读可以考虑悲观锁/乐观锁控制。
数据库的隔离级别可以数据大部分问题,但是也限制了并发性能,为此,提出了悲观锁和乐观锁。
对其他事务修改数据持保守意见,具有排他性。通过在select语句后面添加 for update即可锁定某个数据。(需要关闭自动提交)
允许多个事务访问数据。 使用版本号记录机制实现。为数据记录一条版本标识,事务A和B同时对数据访问,事务A对数据进行操作,版本号值+1。此时事务B也进行操作,提交时检查一下版本号发现与之前读取到的数据不对,不予更新,回滚。
分布式事务指的是允许多个独立的事务资源参与到一个全局的事务中。
单数据源一致性依赖单机事务,多数据的一致性依靠分布式事务。
InnoDB存储引擎提供了对XA事务的支持,并通过XA事务来支持分布式事务的实现(只要是支持XA的不同数据库都行)。此时隔离级别设置为SERIALIZABLE。
XA事务由一个或多个资源管理器RM(resource managers)、一个事务管理器TM(transaction manager)以及一个应用程序(application program)组成。
资源管理器RM:提供访问事务资源的方法,一般是一个数据库。 事务管理器TM:协调各个资源管理器,和他们沟通。 应用程序:指定全局事务中的操作。
分布式事务通常采用2PC协议,该协议主要为了解决在分布式数据库场景下,所有节点(资源管理器)间数据一致性的问题。
分布式事务通过2PC协议将提交分成两个阶段。
在第一阶段,所有参与全局事务的节点都开始准备(PREPARE),告诉事务管理器它们准备好是否提交了。 在第二阶段,事务管理器告诉资源管理器执行ROLLBACK还是COMMIT。
如果任何一个节点显示不能提交,则所有的节点都被告知需要回滚。可见与本地事务不同的是,分布式事务需要多一次的PREPARE操作,待收到所有节点的同意信息后,再进行COMMIT或是ROLLBACK操作。
