C#事务处理可处理两个不同的数据库
我正在处理Oracle数据库上的分布式事务 我有以下代码,见下文和2个问题。 targetConnection和sourceConnection都是Oracle数据库,位于不同的网络上 1) 调用“Complete”方法时,将首先提交哪个命令 2) 当其中一个连接在“完成”方法中丢失时会发生什么情况?例如:到达Complete方法并提交targetCommand,但现在与sourceConnection的连接丢失。在我的例子中,应该回滚整个范围,因为无法提交sourceCommandC#事务处理可处理两个不同的数据库,c#,oracle,transactions,transactionscope,devart,C#,Oracle,Transactions,Transactionscope,Devart,我正在处理Oracle数据库上的分布式事务 我有以下代码,见下文和2个问题。 targetConnection和sourceConnection都是Oracle数据库,位于不同的网络上 1) 调用“Complete”方法时,将首先提交哪个命令 2) 当其中一个连接在“完成”方法中丢失时会发生什么情况?例如:到达Complete方法并提交targetCommand,但现在与sourceConnection的连接丢失。在我的例子中,应该回滚整个范围,因为无法提交sourceCommand priva
private bool MergeRowNew(String mergeStmt, Dictionary<string, object> row, ColumnList columns)
{
bool result = false;
bool targetTransaction = false;
bool sourceTransaction = false;
String mergeStmt2 = "merge into ...";
Exception exception = null;
using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew,
new TransactionOptions { IsolationLevel = System.Transactions.IsolationLevel.ReadCommitted }))
{
try
{
//Using target connection
using (OracleConnection targetConnection = new OracleConnection(this.target.ConnectionString))
{
targetConnection.Open();
//Create new command for target
using (var targetCommand = targetConnection.CreateCommand(mergeStmt))
{
//Add parameters to target command
foreach (Column col in columns)
{
targetCommand.Parameters.Add(col.Name, row[col.Name]);
}
//Affected rows paramaeter
var rowCount = targetCommand.Parameters.Add(":numRows", OracleDbType.Integer, ParameterDirection.Output);
//execute insert in target db
targetCommand.ExecuteNonQuery();
//command succssesful when only one row was affected
if (Convert.ToInt32(rowCount.Value) == 1)
{
targetTransaction = true;
}
}
}
//If target transaction was succssesful then start the local transaction
if (targetTransaction)
{
//Using source connection
using (OracleConnection sourceConnection = new OracleConnection(this.source.ConnectionString))
{
sourceConnection.Open();
using (var sourceCommand = sourceConnection.CreateCommand(mergeStmt2))
{
sourceCommand.Parameters.Add("...","...");
var sourceRowcount = sourceCommand.Parameters.Add(":numRows", OracleDbType.Integer, ParameterDirection.Output);
sourceCommand.ExecuteNonQuery();
//command succssesful when only one row was affected
if (Convert.ToInt32(sourceRowcount.Value) == 1)
{
sourceTransaction = true;
}
}
}
}
}
catch (Exception ex)
{
exception = ex;
}
//if both commands were succssesful then complete the scope
if (targetTransaction && sourceTransaction)
{
scope.Complete();
result = true;
}
} //End scope.
//There was an exception.
if (exception != null)
{
//Do some logging.
}
return result;
}
private bool MergeRowNew(字符串mergesmt、字典行、列列表列)
{
布尔结果=假;
bool-targetTransaction=false;
bool sourceTransaction=false;
字符串mergeStmt2=“合并到…”;
异常=空;
使用(var scope=new TransactionScope)(TransactionScopeOption.RequiresNew,
新事务选项{IsolationLevel=System.Transactions.IsolationLevel.ReadCommitted})
{
尝试
{
//使用目标连接
正在使用(OracleConnection targetConnection=new OracleConnection(this.target.ConnectionString))
{
targetConnection.Open();
//为目标创建新命令
使用(var targetCommand=targetConnection.CreateCommand(mergesmt))
{
//向目标命令添加参数
foreach(列中的列col)
{
targetCommand.Parameters.Add(列名称,行[col.Name]);
}
//受影响行参数
var rowCount=targetCommand.Parameters.Add(“:numRows”,OracleDbType.Integer,ParameterDirection.Output);
//在目标数据库中执行insert
targetCommand.ExecuteOnQuery();
//仅影响一行时命令成功
if(Convert.ToInt32(rowCount.Value)==1)
{
targetTransaction=true;
}
}
}
//如果目标事务成功,则启动本地事务
if(目标交易)
{
//使用源连接
使用(OracleConnection sourceConnection=neworacleconnection(this.source.ConnectionString))
{
sourceConnection.Open();
使用(var sourceCommand=sourceConnection.CreateCommand(mergeStmt2))
{
添加(“…”,“…”);
var sourceRowcount=sourceCommand.Parameters.Add(“:numRows”,OracleDbType.Integer,ParameterDirection.Output);
sourceCommand.ExecuteOnQuery();
//仅影响一行时命令成功
if(Convert.ToInt32(sourceRowcount.Value)==1)
{
sourceTransaction=true;
}
}
}
}
}
捕获(例外情况除外)
{
例外=例外;
}
//如果两个命令都成功,则完成作用域
if(targetTransaction&&sourceTransaction)
{
scope.Complete();
结果=真;
}
}//结束作用域。
//有一个例外。
if(异常!=null)
{
//做一些日志记录。
}
返回结果;
}
1)两个命令将同时提交
2) 如果任何登记的连接失败,则应回滚整个作用域