對兩個數據庫同時操作 ,怎么使用分布式事務

yg1016 2009-04-09 08:59:33
[Transaction(TransactionOption.Required)]
public class StockThreading : ServicedComponent
可是這樣執行會報錯
沒有 MTS 物件內容 (發生例外狀況於 HRESULT: 0x8004E004)
...全文
391 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
mb_1985 2009-04-11
  • 打赏
  • 举报
回复
直接在第一个数据库事务的执行体中开启第二个连接及操作不知可否..
csjtxy 2009-04-11
  • 打赏
  • 举报
回复
Dobzhansky 2009-04-11
  • 打赏
  • 举报
回复
使用多于一个数据库连接的场合下, 事务管理面临一个选择: 是否使用微软 DTS. 这个很重要, 涉及到开发和部署.
yg1016 2009-04-11
  • 打赏
  • 举报
回复
謝謝大家的關注!
我試試先。。。
支持大家繼續討論發言。。。
謝謝。。。
Dobzhansky 2009-04-10
  • 打赏
  • 举报
回复
在 .net 下, 数据库事务存在于一个连接对象上, 如果我们只对一个数据库操作(使用一个连接), 这时启动的事务用连接本身就可以管理了,
这称为 local transaction,
但是如果有两个数据库连接对象开启了一个事务, 即使这两个连接使用的是一个相同的连接字符串, 连接本身也无能为力了, 这时事务不再时 local transaction 了, 开始带有分布式味道, 微软 DTS 就被启动用来管理这些分布式的事务了, 称为事务被 promoted 了, 或者说事务的 Escalation.
比如我测试时候的代码:

string connectionString1 = "server=localhost;database=test;user id=test;password=test;enlist=true";
string connectionString2 = "User Id=scott; Password=tiger; Data Source=Apollo;enlist=true";
//string connectionString3 = "User Id=scott; Password=tiger; Data Source=Apollo;enlist=true";
// 这个 scope 下, 即使使用相同的连接字符, 创建多个连接, 事务还是会被 promote 的
using (TransactionScope tx = new TransactionScope())
{
DbProviderFactory fac = DbProviderFactories.GetFactory("Npgsql");
//DbProviderFactory fac = DbProviderFactories.GetFactory("System.Data.OracleClient");
using (DbConnection connection1 = fac.CreateConnection())
{
connection1.ConnectionString = connectionString1;
connection1.Open();
using (DbCommand command1 = connection1.CreateCommand())
{
command1.CommandText = "insert into dept (deptno) values (50)";
command1.ExecuteNonQuery();
}
//DbProviderFactory factory = DbProviderFactories.GetFactory("Oracle.DataAccess.Client");
DbProviderFactory factory = DbProviderFactories.GetFactory("System.Data.OracleClient");
using (DbConnection connection2 = factory.CreateConnection())
{
connection2.ConnectionString = connectionString2;
connection2.Open();
using (DbCommand command2 = connection2.CreateCommand())
{
command2.CommandText = "insert into tablea (colb) values ('c')";
command2.ExecuteNonQuery();
}
}
}
tx.Complete();
}


分布式事务要求 ado.net provider 提供相关支持, 比如 oracle ado.net provier , 要支持分布式事务, 要求客户端安装 oracle MTS 组件.

同时客户端的DTS 服务也要开启.

com+ 事务, .net 事务, 在微软, 应该使用同样的底层机制,
0 楼的问题估计是 DTS 服务被禁用了, 可以通过组件服务查看器观测一下,
同时看看系统日志有啥详细信息提供.
BossFriday 2009-04-10
  • 打赏
  • 举报
回复
分布式事務,没用过
mark + up
烤火的鱼 2009-04-10
  • 打赏
  • 举报
回复
分布式事务最好还是有数据库来做,写一个存储过程,由客户端来调用,或者子啊客户端组合成一段脚本,扔给服务器执行
Dobzhansky 2009-04-10
  • 打赏
  • 举报
回复
TransactionScope 创建的事务 scope 只对内部创建的连接有效,
对于 ado.net, 事务是数据库连接对上的一个属性,
位于事务 scope 内创建的连接会自动 enlist 到相应的事务中.

你的两个连接是在外面创建的, 那个 using 块内的事务不管理它们.
yg1016 2009-04-10
  • 打赏
  • 举报
回复
修正
stockorderbuyBLL.Add(transaction, o_test1Model);//新增操作(A數據庫的test1表)
stockordertempBLL.Modify(transactionStockName, o_test2Model);//修改操作(B數據庫的test2表)
yg1016 2009-04-10
  • 打赏
  • 举报
回复
對不起,沒及時回復大家!
謝謝Dobzhansky 先!
謝謝大家關注
請教一個問題
//創建事務
SqlTransaction transaction = connectionStock.BeginTransaction();
SqlTransaction transactionStockName = connection.BeginTransaction();

using(TransactionScope scope = new TransactionScope())
{
try
{
stockorderbuyBLL.Add(transaction, o_test1Model);//新增操作(A數據庫的test1表)
stockordertempBLL.Modify(transaction, o_test2Model);//修改操作(B數據庫的test2表)

socpe.Complete();
}catch
{
scope.Dispose();
}
}

這樣執行事務 測試過沒事務效果 ????
請幫忙分析 我錯在哪里???
沒弄明白 學習中。。。。
再次 謝謝 Dobzhansky
同樣歡迎大家有興趣討論、學習。。。
li_dao_hang_1989 2009-04-09
  • 打赏
  • 举报
回复
up……
热学沸腾56 2009-04-09
  • 打赏
  • 举报
回复
学习..up
yagebu1983 2009-04-09
  • 打赏
  • 举报
回复
分布式程序没研究过。。。
关注。。。
hmily821023 2009-04-09
  • 打赏
  • 举报
回复
专业的来了 留名帮顶

62,267

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧