概述
事务控制是保证系统数据完整一致性的基础。也是企业应用系统必须解决的一个技术问题。不单是企业审计上需要,更重要是企业及时有效的通过数据监控企业当前状态的需要。所以对于一个企业级的应用数据的完整一致性是必须的。那么如何简单快速,而又可以从全局上充分的对系统的事务进行有效的控制就显得至关重要了。这里简述系统事务控制的基本概念(数据库的数据一致性问题,数据库的锁机制,数据库的隔离级别的实现),JDBC,JTA的事务控制的实现方法,Spring的事务控制这三方面进行叙述,充分的了解事务控制的细节。
事务的基本概念
数据库事务有严格的定义,它必须同时满足四个特性:原子性(Atomic)、一致性(Consistency)、隔离性(Isolation)和持久性(Durabiliy),简称为ACID。
原子性:表示组成一个事务的多个数据库操作是一个不可分隔的原子单元,只有所有的操作执行成功,整个事务才提交,事务中任何一个数据库操作失败,已经执行的任何操作都必须撤销,让数据库返回到初始状态。
一致性:事务操作成功后,数据库所处的状态和它的业务规则是一致的,即数据不会被破坏。如从A账户转账100元到B账户,不管操作成功与否,A和B的存款总额是不变的。
隔离性:在并发数据操作时,不同的事务拥有各自数据空间,它们的操作不会对对方产生干扰。准确的说,并非要求做到完全无干扰,数据库规定了多种事务隔离级别,不同隔离级别对应不同的干扰程度,隔离级别越高,数据一致性越好,但并发性越弱。
持久性:一旦事务提交成功后,事务中所有的数据操作都必须被持久化到数据库中,即使提交事务后,数据库马上崩溃,在数据库重启时,也必须能保证能够通过某种机制恢复数据。
在这些事务特性中,数据“一致性”是最终目标,其它的特性都是为达到这个目标的措施、要求或手段。 数据库管理系统一般采用重执行日志保证原子性、一致性和持久性。重执行日志记录了数据库变化的每一个动作,数据库在一个事务中执行一部分操作后发生错误退出,数据库即可以根据重执行日志撤销已经执 行的操作。此外,对于已经提交的事务,即使数据库崩溃,在重启数据库时也能够根据日志对尚未持久化的数据进行相应的重执行操作。和Java程序采用对象锁机制进行线程同步类似,数据库管理系统采用数据库锁机制保证事务的隔离性。当多个事务试图对相同的数据进行操作时,只有持有锁的事务才能操作数据,直到前一个事务完成后,后面的事务才有机会对数据进行操作。
多个事务同时访问系统的并发问题。
1)脏读
A读取了B尚未提交的数据,而致使账户损失了500元。
时间 转账事务A 取款事务B
T1 开始事务
T2 开始事务
T3 查询账户余额为1000元
T4 取出500元把余额改为500元
T5 查询账户余额为500元
T6 撤销事务余额恢复为1000元
T7 汇入100元把余额改为600元
T8 提交事务
2)不可重复读
不可重复读是指A事务读取了B事务已经提交的更改数据。假设A在取款事务的过程中,B往该账户转账100元,A两次读取账户的余额发生不一致。
时间 取款事务A 转账事务B
T1 开始事务
T2 开始事务
T3 查询账户余额为1000元
T4 查询账户余额为1000元
T5 取出100元把余额改为900元
T6 提交事务
T7 查询账户余额为900元(和T4读取的不一致)
3)幻影读
A事务读取B事务提交的新增数据,这时A事务将出现幻象读的问题。幻象读一般发生在计算统计数据的事务中,举一个例子,假设银行系统在同一个事务中,两次 统计存款账户的总金额,在两次统计过程中,刚好新增了一个存款账户,并存入100元,这时,两次统计的总金额将不一致。
时间 统计金额事务A 转账事务B
T1 开始事务
T2 开始事务
T3 统计总存款数为10000元
T4 新增一个存款账户,存款为100元
T5 提交事务
T6 再次统计总存款数为10100元(幻象读)
幻象读和不可重复读是两个容易混淆的概念,幻象读是指读到了其它已经提交事务的新增数据,而不可重复读是指读到了已经提交事务的更改数据(更改或删除)。为了避免 这两种情况,采取的对策是不同的,防止读取到更改数据,只需要对操作的数据添加行级锁,阻止操作中的数据发生变化,而防止读取到新增数据,则往往需要添加表级锁——将整个表锁定,防止新增数据。
4)第一类丢失更新
A事务撤销时,把已经提交的B事务的更新数据覆盖了。
时间 取款事务A 转账事务B
T1 开始事务
T2 开始事务
T3 查询账户余额为1000元
T4 查询账户余额为1000元
T5 汇入100元把余额改为1100元
T6 提交事务
T7 取出100元把余额改为900元
T8 撤销事务
T9 余额恢复为1000元(丢失更新)
5) 第二类丢失更新
A事务覆盖B事务已经提交的数据,造成B事务所做操作丢失
时间 转账事务A 取款事务B
T1 开始事务
T2 开始事务
T3 查询账户余额为1000元
T4 查询账户余额为1000元
T5 取出100元把余额改为900元
T6 提交事务
T7 汇入100元
T8 提交事务
T9 把余额改为1100元(丢失更新)
1.2.2 数据库锁机制实现对于上述5类问题的控制
数据并发会引发很多问题,在一些场合下有些问题是允许的,但在另外一些场合下可能却是致命的。数据库通过锁的机制解决并发访问的问题,虽然不同的数据库在实现细节上存在差别,但原理基本上是一样的。
从并发事务锁定的关系上看,可以分为共享锁定和独占锁定。共享锁定会防止独占锁定,但允许其它的共享锁定。而独占锁定既防止其它的独占锁定,也防止其它的共享锁定。
锁就是保护指定的资源,不被其他事务操作。为了最小化锁的成本,自动地以与任务相应等级的锁来锁定资源对象。锁定比较小的对象,例如锁定行,可以提高并发性,但是却有较高的开支。如果锁定许多行, 那么需要占有许多锁对象。锁定比较大的对象,例如锁定表,会大大降低并发性,因为锁定整个表就限制了其他事务访问该表的其他部分,但是成本开支比较低,因为只需维护比较少的锁。 锁是定义到SQL语句上的,对数据进行操作的SQL就是:select,Insert,update ,delete。不同的事物隔离级别,在执行SQL的时候会向表上发送不同的锁。例如在SQLSERVER中的READ COMMITED隔离级别下,SELECT语句会对所有的满足条件的数据行加上共享锁,而UPDATE语句则会对被UPDATE的数据加上排他锁。
以下是一种最为简单的方式通过对锁的应用实现事务间共享数据的隔离。
1)防止第一类丢失更新问题(实现READ_UNCOMMIT隔离级别)
事务在读取数据时,对行数据加共享锁。当且仅当数据没有任何的锁定时候,事务才可以对数据加上独占锁。并且在事务更新完后立即释放独占锁。
2)防止脏读问题(实现READ_COMMIT隔离级别)
事务在读取数据时,对行数据加共享锁。当且仅当数据没有任何的锁定时候,事务才可以对数据加上独占锁。并且当事务提交时候才释放独占锁。
3)防止重复读和第二类丢失更新问题
事务在读取数据的时候直接加独占行级锁,并且当事务结束的时候才释放锁。同一行数据无法支持并发的读操作。
4)防止幻影读问题
事务在读取数据的时候对表加表级独占锁,并且在事务结束的时候释放
注意以上的控制方法关键在于锁定类型和锁的释放时间上进行控制,从而实现不同的隔离级别和数据库的并发访问性。这些方法只是个人的推测,而非数据库的实现。
1.2.3 数据库的隔离级别
尽管数据库为用户提供了锁的DML操作方式,但直接使用锁管理是非常麻烦的,因此数据库为用户提供了自动锁机制。只要用户指定会话的事务隔离级别,数据库 就会分析事务中的SQL语句,然后自动为事务操作的数据资源添加上适合的锁。此外数据库还会维护这些锁,当一个资源上的锁数目太多时,自动进行锁升级以提 高系统的运行性能,而这一过程对用户来说完全是透明的。
ANSI/ISO SQL 92标准定义了4个等级的事务隔离级别,在相同数据环境下,使用相同的输入,执行相同的工作,根据不同的隔离级别,可以导致不同的结果。不同事务隔离级别能够解决的数据并发问题的能力是不同的。数据库一般的默认隔离离级别是“READ COMMITTED”,它能避免脏读,而且有较好的并发性能。尽管它会导致不可重复读、虚读和第二类更新丢失等问题,在可能出现这类问题的个别场合可以由应用程序釆用悲观锁或乐观锁来控制。
SQLSERVER可以使用SET TRANSACTION ISOLATION LEVEL来设置事务的隔离级别。指定隔离级别后,sql会话中所有语句的锁定行为都运行于该隔离级别上,并一直保持有效直到会话终止或者将隔离级别设置为另一个级别。
事务隔离级别对并发问题的解决情况
隔离级别 脏读 不可
重复读 幻象读 第一类丢失更新 第二类丢失更新
READ UNCOMMITED 允许 允许 允许 不允许 允许
READ COMMITTED 不允许 允许 允许 不允许 允许
REPEATABLE READ 不允许 不允许 允许 不允许 不允许
SERIALIZABLE 不允许 不允许 不允许 不允许 不允许
分享到:
相关推荐
这篇博客“事务管理(二)——SQL SERVER的事务管理”可能详细介绍了SQL Server如何处理事务,包括事务的特性、隔离级别以及如何处理事务中的并发问题,如死锁。 首先,事务有四个基本特性,即原子性(Atomicity)...
数据库事务是数据库操作的基本单元,它封装了一组操作,这些操作要么全部执行,要么全部不执行,这一原则被称为ACID(原子性、一致性、隔离性和持久性)特性。原子性保证了事务中的所有操作被视为一个单个操作,即使...
数据库课程设计报告——班级事务管理系统主要涵盖了数据库设计的多个方面,包括需求分析、概念结构设计和逻辑结构设计。以下是对这些知识点的详细说明: 1. **需求分析**: - **数据需求**:系统需要存储并处理...
本课件由王凤彬、李东编著,谢茂康主讲,基于多本权威教材,如周三多、陈传明的《管理学——原理与方法》,张玉利的《管理学》,以及哈罗德·孔茨和海因茨·苇里克的经典著作。 教学内容主要分为四个部分: 1. ...
本书主要阐述事务概念是如何用于解决分布式系统问题的,以及这些概念如何使我们能够在有限的资金和风险范围内建立高性能、高可用性的应用系统。本书内容广泛,从系统的角度全面阐述事务处理的概念和技术,涉及终端上...
### 图书管理系统——数据库——完整版 #### 一、需求分析与系统目标 图书管理系统旨在通过计算机技术,解决传统图书管理中的低效、保密性差等问题,尤其在图书数量庞大时,人工管理变得异常繁琐。该系统的目标是...
Spring框架的核心功能包括一个容器、一个用于配置和组织组件的框架,以及一系列内置于框架中的服务,如事务管理、持久化支持和Web用户界面服务。作为一个轻量级的J2EE框架,Spring为构建和组织J2EE应用程序提供了一...
1. 事务的基本概念 事务是数据库操作的逻辑单元,它包含了多个相关操作,这些操作要么全部执行,要么全部回滚。事务有四个特性,即ACID原则: - 原子性(Atomicity):事务中的所有操作被视为一个不可分割的整体。 ...
《银行管理系统——张孝祥主讲》是一套深入讲解银行管理系统的课程,由业内专家张孝祥主讲,旨在帮助学员全面理解并掌握银行系统的核心技术和应用。此课程结合了8000道面试题,涵盖了银行管理系统的各个方面,旨在...
用户管理子系统是整个教材发放管理系统的核心部分,它负责处理与用户相关的一切事务,包括用户的注册、登录、权限管理、信息维护等,以确保系统的有效运行和数据的安全。 首先,我们要理解“用户管理”的概念。用户...
Java学生管理系统是一款针对初学者设计的项目,旨在帮助他们理解和实践Java编程语言以及数据库管理的基本概念。这个系统主要是用来管理学生的信息,如姓名、学号、年龄、专业等,同时也可能包含其他功能,如成绩管理...
本课程设计旨在通过创建一个班级事务管理系统,让学生掌握数据库设计的基本流程和方法,包括需求分析、概念结构设计、逻辑结构设计以及数据库的创建与完整性约束。以下是该系统的关键知识点: 1. **需求分析**: -...
这篇文档描述的是一个数据库课程设计项目,目标是构建一个班级事务管理系统。系统的主要目的是管理和存储班级成员的信息,包括学生成绩、个人事务以及生活委员的班费管理,旨在提升班级管理的效率和质量。 1. **...
《学生公寓管理系统——SQL纯数据库实践》是一份深入探讨如何运用SQL进行数据库设计与实践的教程,特别关注在学生公寓管理场景下的应用。这个系统涵盖了存储过程和视图的实现,旨在提供一个全面且功能丰富的解决方案...
综上所述,"人事管理系统——数据库课程设计"涵盖了数据库设计的基本原理,包括表的创建、字段定义、关联关系的建立以及数据库文件的使用。通过这个项目,学生不仅能学习到数据库技术,还能理解如何将这些技术应用于...
宾馆酒店住宿管理系统是一款基于毕业设计的管理系统,旨在提升酒店的运营效率和服务质量。系统由季秦宇同学在李秋老师的指导下完成,于2009年4月完成,主要功能包括订房、退房等,适用于职业技术学院计算机网络技术...
这一概念从最初的生产管理逐渐演化到服务运营管理,反映了经济结构从农业社会到工业社会再到服务业社会的转变。 在服务经济中,服务业被分为多个类别,包括基础服务(如通信和交通)、贸易服务(如零售和修理)、...
本文将深入探讨时间管理的概念、误区以及实用的方法和技巧。 时间管理是指通过规划、优先级排序、设定目标和执行策略来优化时间使用的过程。它不仅关乎效率,还涉及效能,即完成最重要任务的能力。时间管理的目标是...
#### 二、事务的基本概念 在讨论 Spring 事务之前,我们先从日常生活中的一个常见场景——取钱说起。当你从 ATM 机上取款时,这一过程可以分为两个主要步骤:首先扣除账户余额,接着吐出现金。这两个步骤必须同时...
事务传播行为是理解Spring事务管理配置时的一个关键概念。除了`PROPAGATION_REQUIRED`外,Spring还支持其他几种传播行为,包括但不限于: - `PROPAGATION_SUPPORTS`:如果当前存在事务,则支持该事务;如果不存在...