三种事务处理
事务处理是在数据处理时经常遇到的问题,经常用到的方法有以下3种总结整理如下:
方法1:直接写入到sql 中
在存储过程中使用 begin trans, commit trans, rollback trans 实现
begin trans
declare @orderdetailserror int,@procunterror int
delete from [order details] where productid=42
select @orderdetailserror [email protected]@error
delete from products where productid=42
select @[email protected]@error
if(@orderdetailserror =0 and @procunterror=0)
commit trans
else
rollback trans
优点:
所有事务逻辑包含在一个单独的调用中
拥有运行一个事务的最佳性能
独立于应用程序
限制:
事务上下文仅存在于数据库调用中
数据库代码与数据库系统有关
方法2 :使用ado.net 实现
使用ado.net 实现,使用这种方式的优点是可以在中间层来管理事务,当然你也可以选择在数据层来实现。
sqlconnection 和oledbconnection 对象有一个 begintransaction 方法,它可以返回 sqltransaction
或者oledbtransaction 对象。而且这个对象有 commit 和 rollback 方法来管理事务
sqlconnection sqlconnection = new sqlconnection("workstation id=weixiaoping;packet size=4096;user id=sa;initial catalog=northwind;persist security info=false");
sqlconnection.open();
sqltransaction mytrans = sqlconnection.begintransaction();
sqlcommand sqlinsertcommand = new sqlcommand();
sqlinsertcommand.connection = sqlconnection
sqlinsertcommand.transaction=mytrans;
try{
sqlinsertcommand.commandtext="insert into tbtree(context,parentid) values('北京',1)";
sqlinsertcommand.executenonquery();
sqlinsertcommand.commandtext="insert into tbtree(context,parentid) values('上海',1)";
sqlinsertcommand.executenonquery();
mytrans.commit();
}catch(exception ex)
{
mytrans.rollback();
}
finally
{
sqlconnection.close();
}
优点:
简单性
和数据据事务差不多的快
独立于数据库,不同数据库的专有代码被隐藏了
缺点:
事务不能跨越多个数据库连接
事务执行在数据库连接层上,所以需要在事务过程中维护一个数据库连接
ado.net分布事务也可以跨越多个数据库,但是其中一个sql server 数据库的话,通过用sql server连接服务器连接到别的数据库,但是如果是在db2和orcal之间就不可以。
以上两种事务是经常用到的事务处理方法。
方法3 com+事务(分布式事务)
.net framework 依靠 mts/com+ 服务来支持自动事务。com+ 使用 microsoft distributed transaction coordinator (dtc) 作为事务管理器和事务协调器在分布式环境中运行事务。
这样可使 .net 应用程序运行跨多个资源结合不同操作(例如,将定单插入 sql server 数据库、将消息写入 microsoft 消息队列 (msmq) 队列、以及从 oracle 数据库检索数据)
的事务。
com+事务处理的类必须继承system.enterpriseservices.servicedcomponent,其实web service就是继承system.enterpriseservices.servicedcomponent,所以web service也支持
com+事务。
定义一个com+事务处理的类
[transaction(transactionoption.required)]
public class dataaccess:system.enterpriseservices.servicedcomponent
{
}
transactionoption枚举类型支持5个com+值(disabled,notsupported,required,requiresnew,supported)
disabled 忽略当前上下文中的任何事务。
notsupported 使用非受控事务在上下文中创建组件。
required 如果事务存在则共享事务,并且如有必要则创建新事务。
requiresnew 使用新事务创建组件,而与当前上下文的状态无关。
supported 如果事务存在,则共享该事务。
一般来说com+中的组件需要required 或supported。当组件用于记录或查帐时requiresnew 很有用,因为组件应该与活动中其他事务处理的提交或回滚隔离开来。
派生类可以重载基类的任意属性。如dataaccess选用required,派生类仍然可以重载并指定requiresnew或其他值。
com+事务有手动处理和自动处理,自动处理就是在所需要自动处理的方法前加上[autocomplete],根据方法的正常或抛出异常决定提交或回滚。
手动处理就是调用contextutil类中enablecommit,setcomplete,setabort方法。
public string testtransaction()
{
try
{
contextutil.enablecommit();
insertarecord1();
insertarecord2();
contextutil.setcomplete();
return "succeed!";
}
catch(exception ex)
{
contextutil.setabort();
return "failed!";
}
}
public void insertarecord1()
{
string strconn="workstation id=weixiaoping;packet size=4096;user id=sa;initial catalog=northwind;persist security info=false";
sqlconnection conn=new sqlconnection(strconn);
conn.open();
sqlcommand command=new sqlcommand("insert into tbtree(context,parentid) values('北京',1)",conn);
command.executenonquery();
conn.close();
}
public void insertarecord2()
{
string strconn="workstation id=weixiaoping;packet size=4096;user id=sa;initial catalog=northwind;persist security info=false";
sqlconnection conn=new sqlconnection(strconn);
conn.open();
sqlcommand command=new sqlcommand("insert into tbtree(context,parentid) values('上海',1)",conn);
command.executenonquery();
conn.close();
}
在需要事务跨 msmq 和其他可识别事务的资源(例如,sql server 数据库)运行的系统中,只能使用 dtc 或 com+ 事务,除此之外没有其他选择。dtc 协调参与分布式事务的所有资源管理器,
也管理与事务相关的操作。
这种做法的缺点是,由于存在 dtc 和 com 互操作性开销,导致性能降低。
com+事务处理的类必须强命名。
新闻热点
疑难解答
图片精选