JDBC事务管理
一、 什么是事务
1.1. 概念
事务(TRANSACTION)是作为单个逻辑工作单元执行的一系列操作。这些操作作为一个整体一起向系统提交,要么都执行、要么都不执行 。事务是一个不可分割的工作逻辑单元。
事务是现代数据库理论中的核心概念之一。如果一组处理步骤或者全部发生或者一步也不执行,我们称该组处理步骤为一个事务。当所有的步骤像一个操作一样被完整地执行,我们称该事务被提交。由于其中的一部分或多步执行失败,导致没有步骤被提交,则事务必须回滚到最初的系统状态。
1.2. ACID原则
事务必须服从ISO/IEC所制定的ACID原则。ACID是原子性(atomicity)、一致性(consistency)、隔离性(isolation)和持久性(durability)的缩写。
原子性(Atomicity):事务是一个完整的操作。事务的各步操作是不可分的(原子的);要么都执行,要么都不执行。
一致性(Consistency):当事务完成时,数据必须处于一致状态 。
隔离性(Isolation):对数据进行修改的所有并发事务是彼此隔离的,这表明事务必须是独立的,它不应以任何方式依赖于或影响其他事务
永久性(Durability):事务完成后,它对数据库的修改被永久保持,事务日志能够保持事务的永久性。
事务的原子性表示事务执行过程中的任何失败都将导致事务所做的任何修改失效。一致性表示当事务执行失败时,所有被该事务影响的数据都应该恢复到事务执行前的状态。隔离性表示并发事务是彼此隔离。持久性表示当系统或介质发生故障时,确保已提交事务的更新不能丢失。持久性通过数据库备份和恢复来保证。
二、 数据库并发问题
当多个用户并发访问数据库中相同的数据时,可能会出现并发问题。
如果没有锁定且多个用户同时访问一个数据库,则当他们的事务同时使用相同的数据时可能会发生问题。并发问题包括:
丢失或覆盖更新。
未确认的相关性(脏读)。
不一致的分析(非重复读)。
幻读。
2.1. 丢失更新
当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,会发生丢失更新问题。每个事务都不知道其他事务的存在。最后的更新将重写由其他事务所做的更新,这将导致数据丢失。
例如,两个编辑人员制作了同一文件的电子复本。每个编辑人员独立地更改其复本,然后保存更改后的复本,这样就覆盖了原始文件。最后保存其更改复本的编辑人员覆盖了第一
个编辑人员所做的更改。如果在第一个编辑人员完成之后第二个编辑人员才能进行更改,则能避免该问题。
2.2. 未确认的相关性(脏读)
当第二个事务选择其他事务正在更新的行时,会发生未确认的相关性问题。第二个事务正在读取的数据还没有确认并且可能由更新此行的事务所更改。
例如,一个编辑人员正在更改电子文件。在更改过程中,另一个编辑人员复制了该文件(该复本包含到目前为止所做的全部更改)并将其分发给预期的用户。此后,第一个编辑人员认为目前所做的更改是错误的,于是删除了所做的编辑并保存了文件。分发给用户的文件包含不再存在的编辑内容,并且这些编辑内容应认为从未存在过。如果在第一个编辑人员确定最终更改前所有人都不能读取更改的文件,则能避免该问题。
2.3. 不一致的分析(非重复读)
当第二个事务多次访问同一行而且每次读取不同的数据时,会发生不一致的分析问题。不一致的分析和未确认的相关性类似,因为其他事务也是正在更改第二个事务正在读取的数
据。然而,在不一致的分析中,第二个事务读取的数据是由已进行了更改的事务提交的。而且,不一致的分析涉及多次(两次或更多)读取同一行,而且每次信息都由其他事务更改;因而该行被非重复读取。
例如,一个编辑人员两次读取同一文件,但在两次读取之间,作者重写了该文件。当编辑人员第二次读取文件时,文件已更改。原始读取不可重复。如果只有在作者全部完成编写后编辑人员才能读取文件,则能避免该问题。
2.4. 幻像读
当对某行执行插入或删除操作,而该行属于某个事务正在读取的行的范围时,会发生幻像读问题。事务第一次读的行范围显示出其中一行已不复存在于第二次读或后续读中,因为该行已被其他事务删除。同样,由于其他事务的插入操作,事务的第二次或后续读显示有一行已不存在于原始读中。
例如,一个编辑人员更改作者提交的文件,但当生产部门将其更改内容合并到该文件的主复本时,发现作者已将未编辑的新材料添加到该文件中。如果在编辑人员和生产部门完成对原始文件的处理之前,所有人都不能将新材料添加到文件中,则能避免该问题。
三、 并发问题的解决方案
当锁定用作并发控制机制时,他能解决并发问题。这使所有事务得以在彼此完全隔离的环境中运行,不过所有时候都能有多个正在运行的事务。可串行性是通过运行一组并发事务达到的数据库状态,等同于这组事务按某种顺序连续执行时所达到的数据库状态。
3.1. sql-92 隔离级别
尽管可串行性对于事务确保数据库中的数据在所有时间内的正确性相当重要,然而许多事务并不总是需求完全的隔离。例如,多个作者工作于同一本书的不同章节。新章节能在任意时候提交到项目中。不过,对于已编辑过的章节,没有编辑人员的批准,作者不能对此章节进行所有更改。这样,尽管有未编辑的新章节,但编辑人员仍能确保在任意时间该书籍项目的正确性。编辑人员能查看以前编辑的章节及最近提交的章节。
事务准备接受不一致数据的级别称为隔离级别。隔离级别是个事务必须和其他事务进行隔离的程度。较低的隔离级别能增加并发,但代价是降低数据的正确性。相反,较高的隔离级别能确保数据的正确性,但可能对并发产生负面影响。
sql-92 定义了下列四种隔离级别:
未提交读(事务隔离的最低级别,仅可确保不读取物理损坏的数据)。
提交读(sql server 默认级别)。
可重复读。
可串行读(事务隔离的最高级别,事务之间完全隔离)。
如果事务在可串行读隔离级别上运行,则能确保所有并发重叠事务均是串行的。
下面四种隔离级别允许不同类型的行为。如表所示:
隔离级别 | 脏读 | 不可重复读 | 幻读 |
未提交读 | 是 | 是 | 是 |
提交读 | 否 | 是 | 是 |
可重复读 | 否 | 否 | 是 |
可串行读 | 否 | 否 | 否 |
提交的东西不能更改 |
事务必须运行于可重复读或更高的隔离级别以防止丢失更新。当两个事务检索相同的行,然后基于原检索的值对行进行更新时,会发生丢失更新。如果两个事务使用一个 update 语句更新行,并且不基于以前检索的值进行更新,则在默认的提交读隔离级别不会发生丢失更新。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论