BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

在TransactionScope中优先使用Oracle的.NET驱动

| 作者 王翔 (Vision Wang) 关注 0 他的粉丝 发布于 2008年1月1日. 估计阅读时间: 7 分钟 | AICon 关注机器学习、计算机视觉、NLP、自动驾驶等20+AI热点技术和最新落地成功案例。

分布式事务(DTx:Distributed Transaction)一直是大型应用所需的必要特性,由于需要同时协调不同的数据源(例如:数据库、队列、甚至注册表和新一代操作系统的I/O),因此启动DTx的代价相对较大,而且很多中间件服务器的DTx协调器与应用位于不同的进程中,因此对于频繁提交的OLTP操作而言性能影响较大。

.NET Framework 2.0开始默认提供ORACLE的ADO.NET驱动,虽然也支持通过TransactionScope隐式启动DTx,但却采用应用宿主进程外的dllhost.exe作为独立的DTx协调器(DTC)。ORACLE在自己的ADO.NET驱动中对该问题进行了显著优化,不仅对反复打开的连接提供了默认的连接池引用重定向,而且把DTx的协调工作置于.NET CLR与应用宿主内部,对于大型应用而言可以有效的减少因跨多进程协调引发的性能损失。

下面的示例代码采用ORACLE的ADO.NET驱动(using Oracle.DataAccess.Client)运行,从COM+的统计看并不会引起DTC调用,而如果换成微软的ORACLE ADO.NET驱动(using System.Data.OracleClient),就需要启动昂贵的DTC服务。

private const string ConnectionString = "Data Source = localhost:1521/XE; User ID = scott; Password = tiger";
private const string SqlConnectionString = "Data Source = (local); Initial Catalog = Northwind; Integrated Security = SSPI";
[TestMethod]
public void TestOracleDriver()
{
     using (TransactionScope scope = new TransactionScope())
     {
        Oracle.DataAccess.Client.OracleConnection connection = new Oracle.DataAccess.Client.OracleConnection(ConnectionString);
        connection.Open();
        Oracle.DataAccess.Client.OracleCommand command = connection.CreateCommand();
        command.CommandText = "UPDATE DEPT SET DNAME = DNAME";
        command.CommandType = CommandType.Text;
        command.ExecuteNonQuery();
        // 为了模拟一个分布式数据的操作,下面还增加了一段SqlConnection的DML操作。
        SqlConnection sqlC = new SqlConnection(SqlConnectionString);
        sqlC.Open();
        SqlCommand sComm = sqlC.CreateCommand();
        sComm.CommandText = "UPDATE Products SET ProductName = ProductName";
        sComm.CommandType = CommandType.Text;
        sComm.ExecuteNonQuery();
        scope.Complete();
    }
}

[TestMethod]
public void TestMicrosoftDriver()
{
    using (TransactionScope scope = new TransactionScope())
    {
        System.Data.OracleClient.OracleConnection connection = new System.Data.OracleClient.OracleConnection(ConnectionString);
        connection.Open();
        System.Data.OracleClient.OracleCommand command = connection.CreateCommand();
        command.CommandText = "UPDATE DEPT SET DNAME = DNAME";
        command.CommandType = CommandType.Text;
        command.ExecuteNonQuery();
        // 为了模拟一个分布式数据的操作,下面还增加了一段SqlConnection的DML操作。
        SqlConnection sqlC = new SqlConnection(SqlConnectionString);
        sqlC.Open();
        SqlCommand sComm = sqlC.CreateCommand();
        sComm.CommandText = "UPDATE Products SET ProductName = ProductName";
        sComm.CommandType = CommandType.Text;
        sComm.ExecuteNonQuery();
        scope.Complete();
    }
}

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我
社区评论

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT