原理:
1. 数据库事务是指作为单个逻辑单元执行的一系列操作。
2. 事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源。
通过将一组相关操作组合为一个要么全部成功要么全部失败的单元,可以简化错误恢复并使应用
程序更加可靠。一个逻辑工作单元要成为事务,必须满足“原子性,一致性,隔离性,和持久性。
3. 事务的原子性:事务必须是原子工作单元,对于其数据修改,要么全部执行,要么全部不执行。通
常,与某个事物相关的操作具有共同的目标,并且是相互依赖的,如果系统只执行这些操作的一个
子集,则可能会破坏事务的总体目标,原子性消除了系统处理操作子集的可能性。
4. 事务的一致性:事务在完成时,必须使所有的数据都保持一致状态。在相关数据库中,所有规则都
必须应用于事务的修改,以保持所有数据的完整性。事务结束时,所有的内部数据结构(如 B 树索
引或双向链表)都必须是正确的。某些维护一致性的责任由应用程序开发人员承担,他们必须确保应
用程序已强制所有已知的完整性约束。
5. 事务的隔离性:由并发事务所作的修改必须与任何其它并发事务所作的修改隔离。事务查看数据时数据
所处的状态,要么是另一并发事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查
看中间状态的数据。
6. 事务的持久性:事务完成之后,它对于系统的影响是永久性的。该修改即使出现致命的系统故障也将一
直保持。
实践:
平台:SQLServer2005
数据库:DBTranscation
表:Table_1
表中只有1列: number
int
使用SQL语句创建一事务:
DECLARE @TranName VARCHAR(20)
SELECT @TranName = 'MyTransaction'
BEGIN TRANSACTION @TranName USE DBTranscation
GO
UPDATE table_1
SET number= number * 2
GO
COMMIT TRANSACTION MyTransaction
GO
运行完后表中的数据都会乘以2
使用C#语言(创建一个控制台程序)
using System;
using System.Data;
using System.Data.SqlClient;
namespace ConsoleApplication1
{
public
class DbTranSql
{
//将事务放到SQL Server中执行
public
void DoTran()
{
//建立连接并打开
SqlConnection
myConn=GetConn();
myConn.Open();
SqlCommand
myComm=new SqlCommand();
try
{
myComm.Connection=myConn;
myComm.CommandText="DECLARE @TranName VARCHAR(20) ";
myComm.CommandText+="SELECT @TranName = 'MyTransaction' ";
myComm.CommandText+="BEGIN TRANSACTION @TranName ";
myComm.CommandText+="USE DBTranscation ";
myComm.CommandText+="UPDATE table_1 SET number = number * 2";
myComm.CommandText+="COMMIT TRANSACTION MyTransaction ";
myComm.ExecuteNonQuery();
}
catch(Exception err)
{
throw
new ApplicationException("事务操作出错,系统信息:"+err.Message);
}
finally
{
myConn.Close();
}
}
//获取数据连接
private SqlConnection GetConn()
{
string
strSql = "Data Source=SZU-JASON;Integrated
Security=SSPI;user id=sa;password=long836133";
SqlConnection myConn=new SqlConnection(strSql);
return myConn;
}
}
public class Program
{
public
static void
{
DbTranSql
tranTest=new DbTranSql();
tranTest.DoTran();
Console.WriteLine("事务处理已经成功完成。");
Console.ReadLine();
}
}
}
使用.net框架
namespace ConsoleApplication2
{
public
class DBSQL
{
private
SqlConnection GetConn()
{
String
strSql = "Data Source=SZU-JASON;Integrated
Security=SSPI;user id=sa;password=long836133";
SqlConnection
myConn = new SqlConnection(strSql);
return
myConn;
}
public
void DoSql(string
sql)
{
SqlConnection
myConn = GetConn();
myConn.Open();
SqlCommand
myComm = new SqlCommand();
SqlTransaction
myTran = myConn.BeginTransaction();
try
{
myComm.Connection =
myConn;
myComm.Transaction =
myTran;
myComm.CommandText =
sql;
myComm.ExecuteNonQuery();
myTran.Commit();
}
catch
(Exception err)
{
throw new ApplicationException(err.Message);
}
finally
{
myConn.Close();
}
}
}
class
Program
{
static
void
{
DBSQL
my = new DBSQL();
my.DoSql("USE DBTranscation;UPDATE Table_1 SET
number=number*2");
Console.ReadLine();
}
}
}
注意,如下的SQL语句不允许出现在事务中:
|
ALTER DATABASE |
修改数据库 |
|
BACKUP LOG |
备份日志 |
|
CREATE
DATABASE |
创建数据库 |
|
DISK INIT |
创建数据库或事务日志设备 |
|
DROP DATABASE |
删除数据库 |
|
DUMP
TRANSACTION |
转储事务日志 |
|
LOAD DATABASE |
装载数据库备份复本 |
|
LOAD
TRANSACTION |
装载事务日志备份复本 |
|
RECONFIGURE |
更新使用 sp_configure 系统存储过程更改的配置选项的当前配置(sp_configure
结果集中的 config_value 列)值。 |
|
RESTORE
DATABASE |
还原使用BACKUP命令所作的数据库备份 |
|
RESTORE LOG |
还原使用BACKUP命令所作的日志备份 |
|
UPDATE
STATISTICS |
在指定的表或索引视图中,对一个或多个统计组(集合)有关键值分发的信息进行更新 |
除了这些语句以外,你可以在你的数据库事务中使用任何合法的SQL语句。
事务回滚:如果在事务处理的过程中,发生未知的不可预料的错误,如何保证事务的原子性呢?当事务中止时,必须执行回滚操作,以便消除已经执
行的操作对数据库的影响。使用myTran.Rollback();使事务回滚到创建该事物创建的时候。
使用存储点:事务只是一种最坏情况下的保障措施,事实上,平时系统的运行可靠性都是相当高的,错误很少发生,因此,在每次事务执行之前都检查其
有效性显得代价太高——绝大多数的情况下这种耗时的检查是不必要的。所以使用存储点就可以提高效率。
先创建一个存储点:myTran.Save("NoUpdate");
在回滚事务时,只需使用Rollback()方法的一个重载函数即可:myTran.Rollback("NoUpdate");
本文参考http://hi.baidu.com/bolove/blog/item/b2397f1e477b3ef41ad5763f.html
浙公网安备 33010602011771号