Connection オブジェクトは、トランザクションがアクティブであると判断した場合、既存の分散トランザクションに自動的に参加します。自動トランザクション参加は、接続が開かれたり、接続プールから取得された場合に行われます。SqlConnection の接続文字列パラメータとして Enlist=false
を指定するか、OleDbConnection の接続文字列パラメータとして OLE DB Services=-7
を指定すると、既存のトランザクションへの自動参加を無効にできます。
自動参加が無効になっている場合は、Connection オブジェクトの EnlistDistributedTransaction メソッドを使用して、既存のトランザクションに参加できます。既存の分散トランザクションに参加すると、トランザクションがコミットまたはロールバックされた場合、データ ソースに対してコードで行った変更もコミットまたはロールバックされます。
EnlistDistributedTransaction は、特に、ビジネス オブジェクトをプーリングしている場合に適しています。ビジネス オブジェクトが、開かれている接続と共にプーリングされている場合は、その接続を開いたり、接続プールから取り出したりするときだけ、自動トランザクション参加が行われます。プーリングされているビジネス オブジェクトを使用して複数のトランザクションが実行される場合、そのオブジェクトの開かれている接続は、新しく開始されるトランザクションには自動参加しません。この場合には、Connection の自動トランザクション参加を無効にし、EnlistDistributedTransaction を使用して、Connection をトランザクションに参加させることができます。
EnlistDistributedTransaction は、既存のトランザクションを参照する、ITransaction 型の引数を 1 つ受け取ります。Connection.EnlistDistributedTransaction を呼び出した後、Connection を使用してデータ ソースに対して行ったすべての変更は、トランザクションに組み込まれます。
メモ Connection は、EnlistDistributedTransaction を呼び出す前に開いておく必要があります。
注意 Connection が BeginTransaction を使用してトランザクションを既に開始している場合、EnlistDistributedTransaction は Exception を返します。ただし、トランザクションがデータ ソースで開始されたローカル トランザクションである場合 (たとえば、SqlCommand を使って BEGIN TRANSACTION ステートメントを明示的に実行した場合)、EnlistDistributedTransaction はローカル トランザクションをロールバックし、要求されたように既存の分散トランザクションに参加します。ローカル トランザクションがロールバックされたことは通知されないため、BeginTransaction で開始したのではないローカル トランザクションについては、自分で管理する必要があります。
トランザクションを必要とする ASP.NET ページの例を次に示します。ページ内の ADO.NET コードは、トランザクションに参加します。
<%@Page Transaction="Required" %>
<%@Import Namespace="System.Data"%>
<%@Import Namespace="System.Data.SqlClient"%>
<%@Import Namespace="System.EnterpriseServices"%>
<html>
<Script Runat="SERVER" Language="VB">
Sub Page_Load()
Dim ns As NorthwindSample = New NorthwindSample()
Dim customerId As String = "CUST1"
Dim companyName As String = "New Company Name"
Try
ns.AddCustomer(customerId, companyName, CType(ContextUtil.Transaction, ITransaction))
ContextUtil.SetComplete()
Response.Write("Customer " & Server.HtmlEncode(customerId) & " added.")
Catch e As Exception
ContextUtil.SetAbort()
Response.Write("Customer " & Server.HtmlEncode(customerId) & " not added. An exception of type " & _
e.GetType().ToString() & " was encountered.")
End Try
End Sub
Public Class NorthwindSample
Public Sub AddCustomer(customerId As String, companyName As String, trans As ITransaction)
Dim nwindConn As SqlConnection = New SqlConnection("Data Source=localhost;Integrated Security=SSPI;" & _
"Initial Catalog=Northwind;Enlist=false;")
Dim cmd As SqlCommand = New SqlCommand("INSERT INTO Customers (CustomerID, CompanyName) " & _
"Values(@CustomerId, @CompanyName)", nwindConn)
cmd.Parameters.Add("@CustomerId", SqlDbType.VarChar, 5).Value = customerId
cmd.Parameters.Add("@CompanyName", SqlDbType.VarChar, 40).Value = companyName
nwindConn.Open()
If Not trans Is Nothing Then
nwindConn.EnlistDistributedTransaction(trans)
End If
Try
cmd.ExecuteNonQuery()
Catch e As SqlException
Throw e
finally
nwindConn.Close()
End Try
End Sub
End Class
</Script>
</html>
[C#]
<%@Page Transaction="Required" %>
<%@Import Namespace="System.Data"%>
<%@Import Namespace="System.Data.SqlClient"%>
<%@Import Namespace="System.EnterpriseServices"%>
<html>
<Script Runat="SERVER" Language="C#">
void Page_Load()
{
NorthwindSample ns = new NorthwindSample();
string customerId = "CUST1";
string companyName = "New Company Name";
try
{
ns.AddCustomer(customerId, companyName, (ITransaction)ContextUtil.Transaction);
ContextUtil.SetComplete();
Response.Write("Customer " + Server.HtmlEncode(customerId) + " added.");
}
catch (Exception e)
{
ContextUtil.SetAbort();
Response.Write("Customer " + Server.HtmlEncode(customerId) + " not added. An exception of type " + e.GetType() + " was encountered.");
}
}
public class NorthwindSample
{
public void AddCustomer(string customerId, string companyName, ITransaction trans)
{
SqlConnection nwindConn = new SqlConnection("Data Source=localhost;Integrated Security=SSPI;" +
"Initial Catalog=Northwind;Enlist=false;");
SqlCommand cmd = new SqlCommand("INSERT INTO Customers (CustomerID, CompanyName) " +
"Values(@CustomerId, @CompanyName)", nwindConn);
cmd.Parameters.Add("@CustomerId", SqlDbType.VarChar, 5).Value = customerId;
cmd.Parameters.Add("@CompanyName", SqlDbType.VarChar, 40).Value = companyName;
nwindConn.Open();
if (trans != null)
nwindConn.EnlistDistributedTransaction(trans);
try
{
cmd.ExecuteNonQuery();
}
catch (SqlException e)
{
throw(e);
}
finally
{
nwindConn.Close();
}
}
}
</Script>
</html>
参照
.NET Framework データ プロバイダによるデータのアクセス | OleDbConnection クラス | OleDbTransaction クラス | SqlConnection クラス | SqlTransaction クラス | OdbcConnection クラス | OdbcTransaction クラス