您的位置:首页 > 其它

.NET三种事务处理详解

2010-03-18 09:42 295 查看
体系结构:SQL事务处理、ADO.NET事务处理、COM+事务处理

 

数据库事务处理:T-SQL语句中完成, Begin Transaction Commit/Roll Back

BEGIN TRANSACTION:


BEGIN
TRANSACTION
{ tran_name}


{trans_name1| @tran_name-veriable1}事务名不得超过32个字符,否则自截断。此处变量的类型仅可以是char、varchar、nchar、nvarchar



WITH MARK ['DESCRIPTION'] 指定在日志中标记事务


EXPRESSION2

BEGIN TRANS启动一个本地事务,但是在应用程序执行一个必须的记录操作之前,他不被记录在事务日志中。

With Mark选项使得事务名被置于事务日志中,将数据还原到早期状态时,可使用标记事务代替日期和时间。

在未标记的数据库事务中可以嵌套标记的事务。如

BEGIN
TRAN T1



UPDATE table1 ...



BEGIN
TRAN M2 WITH MARK



UPDATE table2 ...



SELECT
*
from table1



COMMIT
TRAN M2



UPDATE table3 ...


COMMIT
TRAN T1


命名事务示例:

DECLARE @TranName VARCHAR(20)


SELECT @TranName =
'MyTransaction'


BEGIN
TRANSACTION @TranName


USE AdventureWorks


DELETE
FROM AdventureWorks.HumanResources.JobCandidate



WHERE JobCandidateID = 13


COMMIT
TRANSACTION @TranName


标记事务示例:

BEGIN
TRANSACTION CandidateDelete



WITH MARK N'Deleting a Job Candidate'


USE AdventureWorks


DELETE
FROM AdventureWorks.HumanResources.JobCandidate



WHERE JobCandidateID = 13


COMMIT
TRANSACTION CandidateDelete


COMMIT TRANSACTION:


COMMIT
{TRAN|TRANSACTION}


[transaction_name | [@tran_name_variable ] ]同BEGIN部分的规则


[ ; ]

提交一般事务示例:

USE AdventureWorks


BEGIN
TRANSACTION


DELETE
FROM HumanResources.JobCandidate



WHERE JobCandidateID = 13


COMMIT
TRANSACTION


提交嵌套事务示例:

BEGIN
TRANSACTION OuterTran


    INSERT
INTO TestTran VALUES
(1,
'aaa')


    BEGIN
TRANSACTION Inner1


        INSERT
INTO TestTran VALUES
(2,
'bbb')


        BEGIN
TRANSACTION Inner2


            INSERT
INTO TestTran VALUES
(3,
'ccc')


        COMMIT
TRANSACTION Inner2


    COMMIT
TRANSACTION Inner1


COMMIT
TRANSACTION OuterTran


ROLLBACK TRANSACTION


ROLLBACK
{
TRAN
|
TRANSACTION
}



--transaction_name同上,此处savepoint_name规则同transaction_name,为SAVE TRANSACTION 语句中的savepoint_name,用于条件回滚之影响事务的一部分


[ transaction_name | @tran_name_variable | savepoint_name | @savepoint_variable ]


[ ; ]

示例:

USE TempDB


CREATE
TABLE ValueTable ([value] int)


BEGIN
TRAN Transaction1



INSERT
INTO ValueTable VALUES(1)



INSERT
INTO ValueTable VALUES(2)


SELECT
*
FROM ValueTable


ROLLBACK
TRAN Transaction1


SELECT
*
FROM ValueTable


INSERT
INTO ValueTable VALUES(3)


INSERT
INTO ValueTable VALUES(4)


SELECT
*
FROM ValueTable


DROP
TABLE ValueTable


结果:

综合示例:

begin
TRAN


    declare @orderDetailsError int,@procuntError int


  delete
from [order details] where productid=42


  select @orderDetailsError =@@error


  delete
from products where productid=42


  select @procuntError=@@error


  if(@orderDetailsError =0 and @procuntError=0)


       COMMIT
TRAN


  else


       ROLLBACK
TRAN


ADO.NET事务处理:

示例:


public
void ExecuteNoneSql(string p_sqlstr, params string[] p_cmdStr)


{



using (SqlConnection conn = new
SqlConnection(p_sqlstr))


{


Conn.Open();



SqlCommand cmd = new
SqlCommand();


cmd.Connection = conn;



SqlTransaction trans = null;


trans = conn.BeginTransaction(); //初始化事务


cmd.Transaction = trans; //绑定事务



try


{



for (int i = 0; i < p_cmdStr.Length; i++)


{


cmd.CommandText = p_cmdStr[i];


cmd.CommandType = CommandType.Text;


cmd.ExecuteNonQuery();


}


trans.Commit(); //提交


}



catch (SqlException e)


{



if (trans != null) trans.Rollback(); //回滚



else


{//写日志}


}


}


}

带保存点回滚示例:


using (SqlConnection conn = new
SqlConnection(p_sqlstr))


{


conn.Open();



SqlCommand cmd = new
SqlCommand();


cmd.Connection = conn;



SqlTransaction trans = conn.BeginTransaction("table");


cmd.Transaction = trans;



try


{


cmd.CommandText = "Insert into table_name1 values(values1,values2,....)";


cmd.CommandType = CommandType.Text;


cmd.ExecuteNonQuery();


cmd.CommandText = "Insert into table_name2 values(values1,values2,....)";


cmd.CommandType = CommandType.Text;


cmd.ExecuteNonQuery();


trans.Save("table1");


cmd.CommandText = "Insert into table_name2 values(values1,values2,....)";


cmd.CommandType = CommandType.Text;


cmd.ExecuteNonQuery();


trans.Save("table2");


trans.Commit();


}



catch


{



try


{ trans.Rollback("table2") ; }



catch


{


try{ trans.Rollback("table1") ; }


catch{ trans.Rollback("table") ; }


}


}


}

COM+事务处理:

COM+事务必须继承自System.EnterpriseServices.ServicedComponent。其实WEB也是继承自该类,所以WEB支持COM+事务处理。

第一步、新建一个COM+事务处理的类。

[Transaction(TransactionOption.Required)]



public
class
MyCOMPlus : System.EnterpriseServices.ServicedComponent


{


..............


}

TransactionOption为枚举类型,具有五个选项。

DISABLED忽略当前上下文中的任何事务

NOTSUPPORTED使用非受控事件创建组件

REQUIRED如有事务存在则共享事务,如有必要则创建事务(事务池,事务处理中所选择项)REQUIRESNEW是有新建的事务,与上下文无关

SUPPORTED如果事务存在则共享事务。

一般来说COM+中的组件需要REQUIRED或SUPPORTED。当组件需要同活动中其他事务处理的提交或回滚隔离开来的时候建议使用REQUIRESNEW。COM+事务有手动处理和自动处理,自动处理就是在所需要自动处理的方法前加上[AutoComplete],根据方法的正常或抛出异常决定提交或回滚。手动处理其实就是调用EnableCommit()、SetComplete()、SetAbort()方法。

手动处理示例:


public
void TestTransaction()


{



try


{



ContextUtil.EnableCommit(); //对应BEGIN TRANSACTION


InsertRecord();


DeleteRecord();


UpdateRecord2();



ContextUtil.SetComplete(); //对应TRANSACTION.COMMIT


}



catch (Exception ex)


{



ContextUtil.SetAbort(); //对应TRANSACTION.ROLLBACK


}


}

自动事务处理示例(只需要在方法前面加上AutoComplete的attribute声明即可):

[AutoComplete]



public
void TestTransaction()


{


InsertRecord();


DeleteRecord();


UpdateRecord2();


}

 

三者性能比较:

性能排名: SQL事务处理>ADO.NET事务处理>COM+事务处理

SQL事务处理只需要进行一次数据库交互,优点就是速度很快,而且所有逻辑包含在一个单独的调用中,与应用程序独立,缺点就是与数据库绑定。

ADO.NET需要2n次数据库往返,但相对而言,ADO.NET事务处理性能比SQL事务处理低很少,在一般应用程序中可以忽略。而且ADO.NET事务处理将事务处理与数据库独立,增加了程序的移植性。而且他也可以横跨多个数据库,不过他对于数据库的类型要求一致。

COM+事务处理性能最低,主要因为COM+本身的一些组件需要内存开销。但COM+可以横跨各种数据存储文件,这一点功能是前两者所无法媲美的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: