VB.NETで、SQL-Serverのデータベースにデータの追加をおこないたいのですが、

手動または分散トランザクションモードのため、新規接続を作成できません。
といったエラーが発生します。


Public DB As ADODB.Connection
Dim SQL As Object

Err場所
DB.Execute(SQL)
という記述の場所で、
Err.Description :分散トランザクションモードのため、新規接続を作成できません。
Err.Number:-2147467259
といったエラーコードが発生します。

SQLオブジェクトには、
update abcMst set TPoint=0009000,TCase=00010,TPro=123456,
NDate=GETDATE(),vlterm=’20060621’,LUseDay=’20060621’where memNm=’0001000000’”
となっています。
どなかた教えてください><
かなりお手上げ状態です;;

回答の条件
  • URL必須
  • 1人2回まで
  • 登録:
  • 終了:--
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答3件)

id:cx20 No.1

回答回数607ベストアンサー獲得回数108

ポイント25pt

http://support.microsoft.com/kb/234218/ja/

MTS のトランザクション内で ADO Connection を再利用する方法

URL は関連情報です。


以前、VB6 + ADO の環境で、同様のエラーが発生したことがあります。

これは、ADO の Connection オブジェクトを使いまわしたときに発生する問題のようです。


通常、以下のように同一の Connection オブジェクトを使用して、

2つのレコードセットに対して結果を返そうとすると、

2回目の処理で、内部的に新しい接続(セッション)が作成されてしまいます。


Set rs1 = cn.Execute(”select * from tb_test”)

Set rs2 = cn.Execute(”select * from tb_test”)


このような状態で


cn.BeginTrans

Set rs1 = cn.Execute(”select * from tb_test”)

Set rs2 = cn.Execute(”select * from tb_test”)

cn.CommitTrans


のようにトランザクション指定をすると、

2回目の処理で、新しい接続(セッション)の作成処理が抑制されるため、

今回のようなエラーが発生します。


以下、エラーの再現手順と、修正方法です。


’ エラー発生バージョン

Sub AdoTest1()


  Dim cn As New ADODB.Connection

  Dim rs As New ADODB.Recordset

  

  cn.Open ”PROVIDER=SQLOLEDB;SERVER=(local);DATABASE=db_cx;UID=foo;PWD=bar;”

  cn.BeginTrans

  Set rs = cn.Execute(”select * from tb_test”)

  ’ ↓ 「実行時エラー ’-2147467259 (80004005)’:

  ’   手動または分散トランザクション モードのため、新規接続を作成できません。」

  cn.Execute (”insert into tb_test values( 1, ’bbb’, ’ccc’ )”)

  cn.CommitTrans


End Sub


’ エラー発生しないバージョン

Sub AdoTest2()


  Dim cn As New ADODB.Connection

  Dim rs As New ADODB.Recordset

  

  cn.Open ”PROVIDER=SQLOLEDB;SERVER=(local);DATABASE=db_cx;UID=foo;PWD=bar;”

  cn.BeginTrans

  Set rs = cn.Execute(”select * from tb_test”)

  ’ レコードセットオブジェクトを閉じておく

  rs.Close

  ’ 今度はエラーは発生しないハズ。

  cn.Execute (”insert into tb_test values( 1, ’bbb’, ’ccc’ )”)

  cn.CommitTrans


End Sub

http://www.microsoft.com/japan/com/wpaper/complusapps/complus_da...

COM テクノロジ 技術情報 : Visual Basic 開発者用 COM+ アプリケーション ガイドライン (データ アクセス テクノロジ)

関連情報です。


「複数のコマンド実行において ADO Connection オブジェクトの再使用を回避する」のあたり。

参考情報です。


「8. ADOトランザクションで不可能なこと」のあたり。

id:haul

ありがとうございます。やってみます!

2005/06/23 16:11:59
id:ohex No.2

回答回数23ベストアンサー獲得回数0

ポイント10pt

http://support.microsoft.com/default.aspx?scid=kb;ja;234218

MTS のトランザクション内で ADO Connection を再利用する方法

こちらを参考にすればいかがでしょうか。

id:haul

※この回答を見ていた方すいません、何度か状況が変わったので内容変更します

>x20さんの情報を参考にし、プログラムを修正>したのですが、他のエラーが発生してしまいま>した。

> ’DB.Execute(SQL) ←変更

>  rs=DB.Execute(SQL) ←変更後

>   SQLにデータを入れるプログラム(数行)

> rs.Close()    ←追加

> rs = Nothing   ←追加

> System.Windows.Forms.Application.DoEvents()    ←追加

> DB.Execute(SQL) ←エラーがでていた箇所

>rs.closeで

>Err.Number:3704

>オブジェクトが閉じている場合は、操作は許可されません。というエラーが発生します。

>引き続き調べてみます。

上記問題は解決しました。

上のDB.Execute(SQL)のSQLデータはInsertの為戻り値がありません。その為、rs.closeとやってもエラーが発生します。

ソースは元に戻しました。

となると、rs.closeが問題ではなさそうです。

このプログラムは、VB6.0では問題なく動くので、VB6.0とVB.NETの違いに問題があるかもしれません。

引き続き回答を募集します。

2005/06/23 18:20:09
id:cx20 No.3

回答回数607ベストアンサー獲得回数108

ポイント25pt

URL はダミーです。


> 上のDB.Execute(SQL)のSQLデータはInsertの為戻り値がありません。

> その為、rs.closeとやってもエラーが発生します。


確かに、INSERT 文の実行時であれば、rs(レコードセット)に

代入する必要はありません。


ただ、今回の「分散トランザクションモードのため、新規接続を作成できません。」

のエラーは、レコードセット(データベース カーソル)がオープンされっぱなし

の場合に出るようです(以下参照)。


--------------------------------------------------------------------------------

■ MTS のトランザクション内で ADO Connection を再利用する方法

http://support.microsoft.com/kb/234218/ja/


> 開いているすべてのレコードセットは、ほかの操作を実行する前に、

> 接続を解除するか閉じるかして、何も設定されていない状態にします。


■ COM テクノロジ 技術情報 : Visual Basic 開発者用 COM+ アプリケーション ガイドライン (データ アクセス テクノロジ)

http://www.microsoft.com/japan/com/wpaper/complusapps/complus_da...


> 問題となるのは、他の処理の実行中にデータベース カーソルが開かれたままになることです。

> レコードセットを取得してクライアントに送信する場合は、レコードセットを RDBMS から

> 切断してください。

--------------------------------------------------------------------------------


ですので、DB.BeginTrans ~ DB.CommitTrans の処理の間の、

どこかに、SELECT 文、ないしはレコードセットを返す SP 等が

含まれているのでは?と思います。


もし、DB.Execute(SQL) が複数回呼ばれているのであれば、

処理の回数ぶん、以下の記述を入れてみて下さい。


--------------------------------------------------------------------------------

rs = DB.Execute(SQL)

’ レコードセットがオープンされている場合は、クローズする。

If rs.State = ADODB.ObjectStateEnum.adStateOpen Then

  rs.Close()

End If

--------------------------------------------------------------------------------

> このプログラムは、VB6.0では問題なく動くので、VB6.0とVB.NETの違いに

> 問題があるかもしれません。


参照している ADO のバージョン(MDAC)のバージョンは同じものでしょうか?

異なるバージョンですと動作に違いがあるかもしれません。


また、VB.NET に移行するのであれば、

ADO → ADO.NET への移行を検討した方が良いかもしれません。

(過去の VB の資産がある場合、なかなか移行しづらいとは思いますが・・・)

http://b.hatena.ne.jp/entry/http://www.hatena.ne.jp/1119508352

はてなブックマーク - はてな VB.NETで、SQL-Serverのデータベースにデータの追加をおこないたいのですが、手動または分散トランザクションモードのため、新規接続を作成できません・・

URL は、この質問のブックマークです。


2回までしか回答できませんので、何か参考になる情報がありましたら、

こちらで補足致します。

id:haul

終了いたします。ありがとうございました。

2005/06/28 10:04:34

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません