数据库事务
关键字: 原子性, 一致性, 隔离性, 持久性
数据库事务是指作为单个逻辑工作单元执行的一系列操作。
设想网上购物的一次交易,其付款过程至少包括以下几步数据库操作:
· 更新客户所购商品的库存信息
· 保存客户付款信息--可能包括与银行系统的交互
· 生成订单并且保存到数据库中
· 更新用户相关信息,例如购物数量等等
正常的情况下,这些操作将顺利进行,最终交易成功,与交易相关的所有数据库信息也成功地更新。但是,如果在这一系列过程中任何一个环节出了差错,例如在更新商品库存信息时发生异常、该顾客银行帐户存款不足等,都将导致交易失败。一旦交易失败,数据库中所有信息都必须保持交易前的状态不变,比如最后一步更新用户信息时失败而导致交易失败,那么必须保证这笔失败的交易不影响数据库的状态--库存信息没有被更新、用户也没有付款,订单也没有生成。否则,数据库的信息将会一片混乱而不可预测。
数据库事务正是用来保证这种情况下交易的平稳性和可预测性的技术。
数据库事务的ACID属性
事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源。通过将一组相关操作组合为一个要么全部成功要么全部失败的单元,可以简化错误恢复并使应用程序更加可靠。一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性、一致性、隔离性和持久性)属性:
· 原子性
事务必须是原子工作单元;对于其数据修改,要么全都执行,要么全都不执行。通常,与某个事务关联的操作具有共同的目标,并且是相互依赖的。如果系统只执行这些操作的一个子集,则可能会破坏事务的总体目标。原子性消除了系统处理操作子集的可能性。
· 一致性
事务在完成时,必须使所有的数据都保持一致状态。在相关数据库中,所有规则都必须应用于事务的修改,以保持所有数据的完整性。事务结束时,所有的内部数据结构(如 B 树索引或双向链表)都必须是正确的。某些维护一致性的责任由应用程序开发人员承担,他们必须确保应用程序已强制所有已知的完整性约束。例如,当开发用于转帐的应用程序时,应避免在转帐过程中任意移动小数点。
· 隔离性
由并发事务所作的修改必须与任何其它并发事务所作的修改隔离。事务查看数据时数据所处的状态,要么是另一并发事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看中间状态的数据。这称为可串行性,因为它能够重新装载起始数据,并且重播一系列事务,以使数据结束时的状态与原始事务执行的状态相同。当事务可序列化时将获得最高的隔离级别。在此级别上,从一组可并行执行的事务获得的结果与通过连续运行每个事务所获得的结果相同。由于高度隔离会限制可并行执行的事务数,所以一些应用程序降低隔离级别以换取更大的吞吐量。
· 持久性
事务完成之后,它对于系统的影响是永久性的。该修改即使出现致命的系统故障也将一直保持。
DBMS的责任和我们的任务
企业级的数据库管理系统(DBMS)都有责任提供一种保证事务的物理完整性的机制。就常用的SQL Server2000系统而言,它具备锁定设备隔离事务、记录设备保证事务持久性等机制。因此,我们不必关心数据库事务的物理完整性,而应该关注在什么情况下使用数据库事务、事务对性能的影响,如何使用事务等等。
体验SQL语言的事务机制
作为大型的企业级数据库,SQL Server2000对事务提供了很好的支持。我们可以使用SQL语句来定义、提交以及回滚一个事务。
如下所示的SQL代码定义了一个事务,并且命名为"MyTransaction"(限于篇幅,本文并不讨论如何编写SQL语言程序,请读者自行参考相关书籍):
sql 代码
1.DECLARE @TranName VARCHAR(20)
2.
3.SELECT @TranName = 'MyTransaction'
1.BEGIN TRANSACTION @TranNameGOUSE pubs
1.GO
2.
3.UPDATE roysched
1.SET royalty = royalty * 1.10
1.WHERE title_id LIKE 'Pc%'
1.GO
2.
3.COMMIT TRANSACTION MyTransaction
1.GO
这里用到了SQL Server2000自带的示例数据库pubs,提交事务后,将为所有畅销计算机书籍支付的版税增加 10%。
打开SQL Server2000的查询分析器,选择pubs数据库,然后运行这段程序,结果显而易见。
可是如何在C#程序中运行呢?我们记得在普通的SQL查询中,一般需要把查询语句赋值给SalCommand.CommandText属性,这里也就像普通的SQL查询语句一样,将这些语句赋给SqlCommand.CommandText属性即可。要注意的一点是,其中的"GO"语句标志着SQL批处理的结束,编写SQL脚本是需要的,但是在这里是不必要的。我们可以编写如下的程序来验证这个想法:
c# 代码
1.//TranSql.csusing System;
2.using System.Data;
1.using System.Data.SqlClient;
1.namespace Aspcn
1.{
2. public class DbTranSql
3. {
4. file://将事务放到SQL Server中执行
5. public void DoTran()
6. {
7. file://建立连接并打开
8. SqlConnection myConn=GetConn();myConn.Open();
9. SqlCommand myComm=new SqlCommand();
10. try
11. {
12. myComm.Connection=myConn;
13. myComm.CommandText="DECLARE @TranName VARCHAR(20) ";
14. myComm.CommandText+="SELECT @TranName = 'MyTransaction' ";
15. myComm.CommandText+="BEGIN TRANSACTION @TranName ";
16. myComm.CommandText+="USE pubs ";
17. myComm.CommandText+="UPDATE roysched SET royalty = royalty * 1.10 WHERE title_id LIKE 'Pc%' ";
18. myComm.CommandText+="COMMIT TRANSACTION MyTransaction ";
19. myComm.ExecuteNonQuery();
20. }
21. catch(Exception err)
22. {
23. throw new ApplicationException("事务操作出错,系统信息:"+err.Message);
24. }
25. finally
26. {
27. myConn.Close();
28. }
29. }
30. file://获取数据连接
31. private SqlConnection GetConn()
32. {
33. string strSql="Data Source=localhost;Integrated Security=SSPI;user id=sa;password=";
34. SqlConnection myConn=new SqlConnection(strSql);
35. return myConn;
36. }
37. }
38.
39. public class Test
40. {
41. public static void Main()
42. {
43. DbTranSql tranTest=new DbTranSql();
44. tranTest.DoTran();
45. Console.WriteLine("事务处理已经成功完成。");
46. Console.ReadLine();
47. }
48. }
49.}
注意到其中的SqlCommand对象myComm,它的CommandText属性仅仅是前面SQL代码字符串连接起来即可,当然,其中的"GO"语句已经全部去掉了。这个语句就像普通的查询一样,程序将SQL文本事实上提交给DBMS去处理了,然后接收返回的结果(如果有结果返回的话)。
很自然,我们最后看到了输出"事务处理已经成功完成",再用企业管理器查看pubs数据库的roysched表,所有title_id字段以"PC"开头的书籍的royalty字段的值都增加了0.1倍。
这里,我们并没有使用ADO.net的事务处理机制,而是简单地将执行事务的SQL语句当作普通的查询来执行,因此,事实上该事务完全没有用到.net的相关特性。
了解.net中的事务机制
如你所知,在.net框架中主要有两个命名空间(namespace)用于应用程序同数据库系统的交互:System.Data.SqlClient和System.Data.OleDb。前者专门用于连接Microsoft公司自己的SQL Server数据库,而后者可以适应多种不同的数据库。这两个命名空间中都包含有专门用于管理数据库事务的类,分别是System.Data.SqlClient.SqlTranscation类和System.Data.OleDb.OleDbTranscation类。
就像它们的名字一样,这两个类大部分功能是一样的,二者之间的主要差别在于它们的连接机制,前者提供一组直接调用 SQL Server 的对象,而后者使用本机 OLE DB 启用数据访问。 事实上,ADO.net 事务完全在数据库的内部处理,且不受 Microsoft 分布式事务处理协调器 (DTC) 或任何其他事务性机制的支持。本文将主要介绍System.Data.SqlClient.SqlTranscation类,下面的段落中,除了特别注明,都将使用System.Data.SqlClient.SqlTranscation类。
1:事务的特征:
ACID
A atomic 原子性,一个事务是一个不可分割的单位
C constency 一致性 一个事务开始结束后,数据完整性约束没有被破坏
约束:Fk/pk/not null/unique/check
I isolation 隔离性 一个事物的执行,与其他事物的关系
D durable 持久性,数据应该持久保存
2:事务的边界 JDBC规范的61 页
auto commit :
JDBC默认是true
* 默认情况下事务的边界auto commit=true:
对于insert update delete statement执行结束的时候会提交事务
* auto commit=false
只能显示声明事务的提交,如果不显示声明,connection在关闭的时候会
检查,然后提交事务
* 设置为 auto commit=false
在一个事物用到多个statement的时候要显示声明auto commit=false】
3: 事务的隔离级别:
* 脏读
允许读取到别的事务修改但是未提交的数据
* 不可重复读
在一个事务中多次读取一条数据,读取后的结果不一致(数据被别的事务更改);
* 幻像读
在一个事务中多次读取后,读取了别的事务插入进来的数据
* transaction read uncommitted
允许读取到别的事务修改但是未提交的数据
* transaction read committed
只能读取到别的事务已经提交的数据,未提交的读取不到改变
* transaction repeatable read
在一个事务中多次读取一条数据,读取后的结果一致(数据被别的事务更改读取结果一样
)
* transaction serializable
在一个事务中多次读取后,读取不到别的事务插入进来的数据
4:savepoint: 给事务提供了更好的细粒度控制。
分享到:
相关推荐
数据库事务:对数据库事务的讲解,事务的概念 理解事务的特性、分类
数据库事务是数据库操作的核心概念,尤其在C#编程中,理解并熟练运用数据库事务对于确保数据的完整性和一致性至关重要。数据库事务确保了在多步骤操作中,如果其中一个步骤失败,整个事务可以被回滚,从而避免了数据...
总结来说,数据库事务的四大特性是保证数据库操作可靠性和正确性的基石。理解并正确应用这些特性,对于设计和维护高可用、高可靠的数据库系统至关重要。在实际开发中,开发者需要根据业务需求选择合适的事务隔离级别...
### 数据库事务应用详解 #### 事务处理的重要性与ACID特性 事务处理是现代数据库管理系统(DBMS)中不可或缺的一部分,尤其对于那些涉及复杂业务逻辑、需要确保数据一致性和完整性的应用来说更是如此。事务处理的...
事务的四个特性,即ACID属性,是原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。原子性保证事务中的所有操作要么全部完成,要么全部不完成,一致性则保证事务完成后,...
总结起来,事务是数据库操作的关键组成部分,它的隔离性、回滚和隐式事务特性确保了数据的一致性和完整性。在处理并发操作和错误恢复时,深入理解和正确使用事务至关重要。在实际开发中,我们需要根据业务需求和性能...
分布式数据库事务处理是数据库系统中的一个重要概念,尤其是在大型企业级应用和互联网服务中,它能够保证数据的一致性和完整性,即使在多台计算机之间进行数据操作。COM+(Component Object Model Plus)是微软提出...
总的来说,数据库事务管理涉及事务的定义、状态管理、ACID特性的实现以及并发控制策略,如封锁协议,这些都是保证数据库在多用户环境下的正确性和可靠性的核心组成部分。通过精细的事务管理和有效的并发控制,数据库...
事务是数据库操作的基本单元,确保数据的一致性和完整性。在Java编程中,处理事务主要涉及JDBC(Java Database Connectivity)和JTA(Java Transaction API)。理解这些概念对于开发可靠的、高性能的数据库应用至关...
数据库之事务调优是数据库管理中的一个重要环节,它关乎到系统的性能、稳定性和并发处理能力。事务是数据库操作的基本单位,确保数据的一致性、...通过这些方法,我们可以构建出一个高效、稳定的数据库事务处理系统。
数据库事务管理及锁机制原理剖析:包括事务特性 ACID、数据隔离级别、事务实现的原理、锁机制,及过程中可能遇到的查询效率及死锁问题等
"数据库基础数据库事务处理" 数据库事务处理是数据库系统的基本概念,允许用户对数据进行更改,然后...数据库事务处理可以分为隐式和显式两种模式。显式事务操作通过命令实现,隐式事务操作则由数据库系统自动管理。
在模拟数据库事务时,可能会用到这些机制来管理事务间的隔离级别,如读未提交(Read Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable Read)和串行化(Serializable)。 4) **Java设计模式**:在...
在实际应用中,开发者需要根据具体需求和数据库系统的特性,合理设计事务边界,以及在必要时添加锁定或保存点,以确保数据的正确性和系统的稳定性。理解并掌握事务处理方法对于构建高效、可靠的数据库应用至关重要。
本文将深入探讨C#语言中与数据库事务相关的原理及实践,包括事务的定义、特性、类型,以及如何在C#中利用Entity Framework(EF)进行事务开发和管理。 首先,我们需要理解什么是事务。在数据库系统中,事务是一组...
在“数据库事务处理基础——设计与实现”这个主题中,我们将深入探讨数据库事务的各个方面,包括其定义、特性、类型以及如何在实际应用中进行设计和实现。 数据库事务是数据库操作的基本单元,它封装了一组操作,...
首先,理解数据库事务的基本特性至关重要: 1. 原子性(Atomicity):事务中的所有操作视为一个单元,要么全部完成,要么全部不完成。 2. 一致性(Consistency):事务完成后,数据库状态从一个一致状态转换到另一个...
综上所述,数据库市场提供了多种类型的产品,每种都有其独特的特性和适用场景。在选择数据库时,需要根据业务需求、数据类型、性能要求以及成本等因素综合考虑。同时,管理和监控工具、数据治理策略以及许可证协议都...