代码如下
try
{
using (TransactionScope scope=new TransactionScope())
{
AddForSqlserver("insert into test values (1,'aaa')");
AddForOracle("insert into test values ('001','aaa',1)");
AddForOracle("insert into test values ('001','aaa')");
scope.Complete();
}
}
catch (Exception ex)
{
}
执行难第三条sql 会插入失败,sqlsqlver的数据时没有被插入的,但是第二条oracle的数据确被插入了。
private void AddForOracle(string sql)
{
using (var conn = new OracleConnection(str))
{
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandText = sql;
cmd.CommandType = CommandType.Text;
try
{
int n = cmd.ExecuteNonQuery();
if (n <= 0)
{
throw new Exception("操作失败");
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
cmd.Clone();
cmd.Dispose();
cmd = null;
}
}
}
在线求高人指点。。。。事实上我遇到的问题是这样的,现在我本地应用程序需要操作位于不同网络节点不同的数据库、资源,开启了MSDTC服务,在调用transactionscope进行事务控制的时候sqlserver是能够实现的,但是遇到oracle数据库操作时候发现,事务流转功能为并未实现,刚才高人说需要我oracle cmd开启oracletransaction.,是不是必须要在oracle数据库操作时开启oracletransaction才能实现oracle数据库操作的事务控制呢?
你给你的 cmd 设置 Transaction 属性。
没有明白,我执行的所有sql应该是在同一个环境事务里面的
@大灰机: 我知道,那是对于SQL SERVER来说的,同时还需要在连接字符串中设置 Enlist=true 。Oracle的就不一定了,需要 Oracle Client 组件支持。
你可以下载一个 ODP.NET (好像新版是纯托管代码的),ADO.NET中的Oracle不被支持了。
@Launcher: 我也想到过这个问题,现在组件是oracle提供的程序集 Oracle.DataAccess.dll, v1.0.3705
@大灰机:如果非要使用分布式事务的话,建议看看这篇文章: http://www.infoq.com/cn/news/2007/12/adonet-oracle-ts
根据你使用的.Net Framework版本,你可以去Oracle官网下载适配的ODP.NET,上面还有一些用例。你可以先单独测试下 Oracle 的事务,成功后再结合 Sql Server。
你应该设置一个标记。比如bool Flag=true;
然后,按照你的操作,有三个插入操作要放在这个事物中,只要有一个不成功,你就把执行Flag=false;
using(TransactionScope ts = new TransactionScope())
{
if(!插入1){Flag=false;}
if(!插入2){Flag=false;}
if(!插入3){Flag=false;}
if(Flag){scope.Complete();}
}
试试吧。。
这个只是一个测试用例,实际上应用场景执行的操作资源的地方可能位于不同的网络节点上
@大灰机: 所以你的问题是?不太明白。
@jone_e: http://msdn.microsoft.com/zh-cn/library/vstudio/system.transactions.transactionscope.aspx
@jone_e: 问题就是Oracle.DataAccess中提交数据时不能感知当前环境事务。