事务的ACID属性如下:
原子性(Atomicity):事务的所有操作是原子工作单元;对于其数据修改,要么全都执行,要么全都不执行。原子性消除了系统处理操作子集的可能性。
一致性(Consistency):数据从一种正确状态转换到另一种正确状态。事务在完成时,必须使所有的数据都保持一致。在相关数据库中,所有规则都必 须应用于事务的修改,以保持所有数据的完整性。当事务结束时,所有的内部数据结构都必须是正确的。在存款取款的例子中,逻辑规则是,钱是不能凭空产生或销 毁的,对于每个(收支)条目必须有一个相应的抵衡条目产生,以保证账户是平的。
隔离性(Isolation):由并发事务所作的修改必须与任何其他并发事务所作的修改隔离。查看数据时数据所处的状态,要么是事务修改它之前的状态,要 么是事务修改它之后的状态。简单的理解就是,防止多个并发更新彼此干扰。事务在操作数据时与其他事务操作隔离。隔离性一般是通过加锁的机制来实现的。
持久性(Durability):事务完成之后,它对于系统的影响是永久性的。已提交的更改即使在发生故障时也依然存在。
对于事务的开发,.NET平台也为我们提供了几种非常简单方便的事务机制。无论是在功能上还是性能上都提供了优秀的企业级事务支持。
.NET开发者可以使用以下5种事务机制:
1.SQL和存储过程级别的事务。
2.ADO.NET级别的事务。
3.ASP.NET页面级别的事务。
4.企业级服务COM+事务。
5.System.Transactions 事务处理。
这5种事务机制有着各自的优势和劣势,分别表现在性能、代码数量和部署设置等方面。开发人员可以根据项目的实际情况选择相应的事务机制。
链接数据库创建事务
一、数据库事务
二、现在我们对事务的概念和原理都有所了解了,并且作为已经有一些基础的C#开发者,我们已经熟知编写数据库交互程序的一些要点,即:
(1)使用SqlConnection类的对象的Open()方法建立与数据库服务器的连接。
(2)然后将该连接赋给SqlCommand对象的Connection属性。
(3)将欲执行的SQL语句赋给SqlCommand的CommandText属性。
(4)通过SqlCommand对象进行数据库操作。
创建一 个ADO.NET事务是很简单的,需要定义一个SqlTransaction类型的对象。SqlConnection 和OleDbConnection对象都有一个 BeginTransaction 方法,它可以返回 SqlTransaction 或者OleDbTransaction 对象。然后赋给SqlCommand对象的Transcation属性,即实现了二者的关联。为了使事务处理可以成功完成,必须调用 SqlTransaction对象的Commit()方法。如果有错误,则必须调用Rollback()方法撤销所有的操作。
三、ADO.NET事务的优势和限制如下。
优势:
1.简单。
2.和数据库事务差不多快。
3.事务可以跨越多个数据库访问。
4.独立于数据库,不同数据库的专有代码被隐藏了。
限制:事务执行在数据库连接层上,所以需要在执行事务的过程中手动地维护一个连接。
注意:所有命令都必须关联在同一个连接实例上,ADO.NET事务处理不支持跨多个连接的事务处理。
ASP.NET 事务可以说是在.NET平台上事务实现方式最简单的一种,你仅仅需要一行代码即可。在aspx的页面声明中加一个额外的属性,即事务属性 Transaction="Required",它有如下的值:Disabled(默认)、NotSupported、Supported、 Required和RequiresNew,这些设置和COM+及企业级服务中的设置一样,典型的一个例子是如果你想在页面上下文中运行事务,那么要将其 设置为Required。如果页面中包含有用户控件,那么这些控件也会包含到事务中,事务会存在于页面的每个地方。5.4.3 ASP.NET页面级别的事务
页面申明(Transaction="Required")
<%@ Page Transaction="Required" Language="C#" AutoEventWireup="true" CodeBehind="WebForm3.aspx.cs" Inherits="WebApplication4.WebForm3" %>
protected void Button1_Click(object sender, EventArgs e) { try { Work1(); Work2(); ContextUtil.SetComplete(); //提交事务 } catch (System.Exception except) { ContextUtil.SetAbort(); //撤销事务 Response.Write(except.Message); } }
四、企业级服务COM+事务
.NET Framework 依靠 MTS/COM+ 服务来支持自动事务处理。COM+ 使用 Microsoft Distributed Transaction Coordinator(DTC)作为事务管理器和事务协调器在分布式环境中运行事务。这样可使 .NET 应用程序运行跨多个资源结合不同操作(例如将定单插入SQL Server 数据库、将消息写入 Microsoft 消息队列(MSMQ)队列,以及从 Oracle 数据库检索数据)的事务。
要 实现COM+事务处理的类则必须继承System.EnterpriseServices.ServicedComponent,这些类需要是公共的,并 且需要提供一个公共的默认的构造器。其实Web Service就是继承ServicedComponent,所以Web Service也支持COM+事务。要在类定义之前加属性[Transaction(TransactionOption.Required)]。类里面 的每个方法都会运行在一个事务中。
定义一个COM+事务处理的类:
首先引用:using System.EnterpriseServices;
然后继承:ServicedComponent。
[Transaction(TransactionOption.Required)]
public class OrderData : ServicedComponent
{
}
TransactionOption枚举类型支持5个值:Disabled、NotSupported、Required、RequiresNew和Supported,如表
值
|
说 明
|
Disabled
|
忽略当前上下文中的任何事务
|
NotSupported
|
使用非受控事务在上下文中创建组件
|
Required
|
如果事务存在则共享事务,并且如有必要则创建新事务
|
RequiresNew
|
使用新事务创建组件,而与当前上下文的状态无关
|
Supported
|
如果事务存在,则共享该事务
|
一般来说COM+中的组件需要Required 或Supported。当组件用于记录或查账时RequiresNew 很有用,因为组件应该与活动中其他事务处理的提交或回滚隔离开来。
派生类可以重载基类的任意属性。如OrderData选用Required,派生类仍然可以重载并指定RequiresNew或其他值。
COM+ 事务有手动处理和自动处理两种方式,自动处理就是在所需要自动处理的方法前加上[AutoComplete],根据方法的正常或抛出异常决定提交或回滚。 手动处理就是调用ContextUtil类中的EnableCommit、SetComplete和SetAbort方法。
手动处理()
自动处理(这样如果方法执行时没有异常就默认提交,如果有异常则这个方法就会回滚。)
[Transaction(TransactionOption.Required)] public class Class1: ServicedComponent { [AutoComplete(true)]//自动执行事务 void Dome() { } }
Linq语句执行事务:db.savechange()继承了事务,在出现程序错误的情况会自动回滚,但如果不满足我们的逻辑需要回滚数据,需要手动调用事务操作
private readonly static JierDataEntities db = new JierDataEntities(); //添加购物车 public static bool ShoppingCartInfoAdd(ShoppingCart s) { db.Database.BeginTransaction();//创建事务 db.ShoppingCart.Add(s); //进行数据回滚 db.Database.CurrentTransaction.Rollback(); return db.SaveChanges()>0; }