Introduction
.NET COM+ Transactions<o:p>
<o:p>
Introduction:<o:p>
<o:p>
Most of the components are used to access or retrieve data from the database. These components are best done using the transaction in order to get the advantages of the Transaction built in the .Net. As we have learned from the DBMS concepts that the advantages of Transaction is summarized as ACID. A-Atomicity. C-Consistency. I-Isolation. D-Durability. Now, we don’t have to worry about the ACID. .Net Takes care of it.<o:p>
<o:p>
Let us see the steps used to create the .Net COM+ Transaction:<o:p>
<o:p>
- Use the built in .Net Transaction objects.<o:p>
<o:p>
- Use ApplicationName Atribute that will hold the assembly Components.<o:p>
<o:p>
- Use ApplicationActivation.ActivationOption attribute specifies where assembly components are loaded on activation.<o:p>
<o:p>
4. Use the AssemblyKeyFile specifies the name of the strong key that will be used to sign the assembly.<o:p>
<o:p>
- Use Transaction.TransactionOption attribute to specify that the class requires the transaction or not.<o:p>
<o:p>
- Write your code for the class. (The class name has to inherit from ServicedComponent Class.<o:p>
<o:p>
- Use Serializable attribute to support serialization of the exception as it goes from COM+ to the client.<o:p>
<o:p>
- Build the Component.<o:p>
<o:p>
9. Access the Component from the Interface.<o:p>
<o:p>
<o:p>
<o:p>
And now we are going to the real thing:<o:p>
<o:p>
- Use the built in .Net Transaction objects.<o:p>
<o:p>
using System;<o:p>
using System.Data;<o:p>
using System.Data.OleDb;<o:p>
using System.Reflection;<o:p>
using System.EnterpriseServices; //This is must when you want to use component.<o:p>
using System.Runtime.InteropServices; //This is for component interoperability.<o:p>
using System.Runtime.Serialization;//This is for serialization.<o:p>
<o:p>
- Use ApplicationName Atribute that will hold the assembly Components.<o:p>
<o:p>
[assembly: ApplicationName("SRS")]<o:p>
<o:p>
<o:p>
<o:p>
- Use ApplicationActivation.ActivationOption attribute specifies where assembly components are loaded on activation.<o:p>
<o:p>
[assembly: ApplicationActivation(ActivationOption.Library)]<o:p>
<o:p>
<o:p>
Use the AssemblyKeyFile specifies the name of the strong key that will be used to sign the assembly. <o:p>
<o:p>
(The .snk file was generated with sn.exe)<o:p>
Note: use it in .net command prompt example in the same Com+ project folder: <o:p>
C:\SRS>sn –k SRS.snk<o:p>
<o:p>
#if BuildBat // Used when building from the command line<o:p>
[assembly: AssemblyKeyFile("SRS.snk")]<o:p>
#else // Used when building from within Visual Studio .NET<o:p>
[assembly: AssemblyKeyFile("SRS.snk")]<o:p>
#endif<o:p>
<o:p>
<o:p>
Here you actually have the namespace. When you create a project the .Net creates a namespace for you with the same name of your project. Example we create a SRS. (Student Registration System), we will have namespace like this. <o:p>
<o:p>
namespace SRS<o:p>
{<o:p>
<o:p>
}<o:p>
<o:p>
<o:p>
Note: Inside the namespace we write all our code which is in step no. 5 & 6<o:p>
<o:p>
5. Use Transaction.TransactionOption attribute to specify that the class requires the transaction or not.<o:p>
<o:p>
[Transaction(TransactionOption.Required)]<o:p>
<o:p>
<o:p>
6. Write your code for the class. (The class name has to inherit from ServicedComponent Class.<o:p>
<o:p>
<o:p>
public class Term : ServicedComponent<o:p>
{<o:p>
// This method returns the List of Advising Terms in the Dataset<o:p>
protected string ConnString;<o:p>
protected OleDbConnection connection;<o:p>
// First the SQLConnection needs to be setup.<o:p>
public string ConnectionString <o:p>
{<o:p>
get<o:p>
{<o:p>
return ConnString;<o:p>
}<o:p>
set<o:p>
{<o:p>
ConnString = value;<o:p>
}<o:p>
}<o:p>
public OleDbConnection Connection <o:p>
{<o:p>
get<o:p>
{<o:p>
if(ConnString==null)<o:p>
{<o:p>
throw new ConnectionStringException();<o:p>
}<o:p>
if (connection== null)<o:p>
{<o:p>
connection = new OleDbConnection(ConnString); <o:p>
}<o:p>
return connection;<o:p>
}<o:p>
}<o:p>
public void CloseDatabaseOnError()<o:p>
{<o:p>
try<o:p>
{<o:p>
Connection.Close();<o:p>
}<o:p>
catch<o:p>
{<o:p>
}<o:p>
}<o:p>
public DataSet GetAdvisingTerms()<o:p>
{<o:p>
DataSet termDS = new DataSet();<o:p>
try<o:p>
{ <o:p>
Connection.Open();<o:p>
OleDbCommand oledbCommand = new OleDbCommand();<o:p>
oledbCommand.Connection = Connection;<o:p>
oledbCommand.CommandType = CommandType.StoredProcedure;<o:p>
oledbCommand.CommandText = "Ssp_SRS_GetAdvisingTerms";<o:p>
OleDbDataAdapter termDA = new OleDbDataAdapter();<o:p>
termDA.SelectCommand = oledbCommand;<o:p>
<o:p>
termDA.Fill(termDS, "Ssp_SRS_GetAdvisingTerms");<o:p>
Connection.Close();<o:p>
<o:p>
}<o:p>
catch(Exception e)<o:p>
{<o:p>
CloseDatabaseOnError();<o:p>
throw new AdvisingTermNotReadException(e);<o:p>
}<o:p>
return termDS ;<o:p>
}<o:p>
<o:p>
<o:p>
}<o:p>
<o:p>
Note: The Class has to be declared as public so that you can call it anywhere you want to use it.<o:p>
<o:p>
7. Use Serializable attribute to support serialization of the exception as it goes from COM+ to the client.<o:p>
<o:p>
// AdvisingTermNotReadException occurs when there is an error //while reading the <o:p>
// advising terms from the database.<o:p>
[Serializable]<o:p>
public class AdvisingTermNotReadException : Exception<o:p>
{<o:p>
public AdvisingTermNotReadException(Exception ex) : <o:p>
base("Unable to get the advising term from the database. "+ex.Message , ex)<o:p>
{<o:p>
}<o:p>
<o:p>
public AdvisingTermNotReadException(SerializationInfo info, <o:p>
StreamingContext context) : base(info, context) <o:p>
{<o:p>
}<o:p>
}<o:p>
<o:p>
- Build the component.<o:p>
Create a build.bat file and put it in the project folder.<o:p>
The build.bat will contain the following:<o:p>
<o:p>
csc /target:library %DEBUGSAMPLE% /d:BuildBat /out:SRS.dll /r:System.EnterpriseServices.dll /r:System.dll /r:System.Data.dll *.cs<o:p>
<o:p>
regsvcs SRS.dll<o:p>
gacutil -i SRS.dll<o:p>
<o:p>
@echo.<o:p>
@echo To uninstall the Transactions Sample, run "build -u"<o:p>
@echo.<o:p>
<o:p>
@goto exit<o:p>
<o:p>
:clean<o:p>
gacutil /u SRS,PublicKeyToken=b7073b6138b34cac<o:p>
regsvcs /u SRS.dll<o:p>
<o:p>
:exit<o:p>
<o:p>
Move to Programs > Microsoft Visual Studio .Net> Microsoft Studio .Net Tools > Visual Studio .NET Command Prompt.<o:p>
<o:p>
Move to where your project is located, then,<o:p>
use Build command to build the component. Example:<o:p>
c:\SRS>build<o:p>
<o:p>
Now you are ready to use the component.<o:p>
<o:p>
- Access the Component from the Interface. Example from a Button or Page_Load() function etc. This is usually another project accessing the component.<o:p>
<o:p>
Note: Do not forget to Reference the dll component.<o:p>
To Do this: right click references > browse > c:\SRS\SRS.dll<o:p>
The SRS.dll will loaded in your project.<o:p>
You also do the same for the System.EnterpriseServices<o:p>
<o:p>
Using(SRS.Term _Term = new SIS.Term())<o:p>
{<o:p>
DataSet DSTerm = new DataSet();<o:p>
DSTerm = _Term.GetAdvisingTerms()<o:p>
<o:p>
//To retrieve the data<o:p>
int i;<o:p>
i = DSTerm.Tables.Rows.Count;<o:p>
while(i > 0)<o:p>
{<o:p>
Response.Write(DSTerm.Tables.Rows[i-1][“Term_Desc”].ToString());<o:p>
}<o:p>
}<o:p>
<o:p>
<o:p>
Code used with this Article consists of 3 files:
<o:p>
<o:p><o:p>
1. Term.cs<o:p>
<o:p>
using System;<o:p>
using System.Data;<o:p>
using System.Data.OleDb;<o:p>
using System.Reflection;<o:p>
using System.EnterpriseServices; //This is must when you want to use component.<o:p>
using System.Runtime.InteropServices; //This is for component interoperability.<o:p>
using System.Runtime.Serialization;//This is for serialization.<o:p>
<o:p>
[assembly: ApplicationName("SRS")]<o:p>
[assembly: ApplicationActivation(ActivationOption.Library)]<o:p>
<o:p>
#if BuildBat // Used when building from the command line<o:p>
[assembly: AssemblyKeyFile("SRS.snk")]<o:p>
#else // Used when building from within Visual Studio .NET<o:p>
[assembly: AssemblyKeyFile("SRS.snk")]<o:p>
#endif<o:p>
<o:p>
namespace SRS<o:p>
{<o:p>
<o:p>
[Transaction(TransactionOption.Required)]<o:p>
<o:p>
public class Term : ServicedComponent<o:p>
{<o:p>
// This method returns the List of Advising Terms in the Dataset<o:p>
protected string ConnString;<o:p>
protected OleDbConnection connection;<o:p>
// First the SQLConnection needs to be setup.<o:p>
public string ConnectionString <o:p>
{<o:p>
get<o:p>
{<o:p>
return ConnString;<o:p>
}<o:p>
set<o:p>
{<o:p>
ConnString = value;<o:p>
}<o:p>
}<o:p>
public OleDbConnection Connection <o:p>
{<o:p>
get<o:p>
{<o:p>
if(ConnString==null)<o:p>
{<o:p>
throw new ConnectionStringException();<o:p>
}<o:p>
if (connection== null)<o:p>
{<o:p>
connection = new OleDbConnection(ConnString); <o:p>
}<o:p>
return connection;<o:p>
}<o:p>
}<o:p>
public void CloseDatabaseOnError()<o:p>
{<o:p>
try<o:p>
{<o:p>
Connection.Close();<o:p>
}<o:p>
catch<o:p>
{<o:p>
}<o:p>
}<o:p>
public DataSet GetAdvisingTerms()<o:p>
{<o:p>
DataSet termDS = new DataSet();<o:p>
try<o:p>
{ <o:p>
Connection.Open();<o:p>
OleDbCommand oledbCommand = new OleDbCommand();<o:p>
oledbCommand.Connection = Connection;<o:p>
oledbCommand.CommandType = CommandType.StoredProcedure;<o:p>
oledbCommand.CommandText = "Ssp_SRS_GetAdvisingTerms";<o:p>
OleDbDataAdapter termDA = new OleDbDataAdapter();<o:p>
termDA.SelectCommand = oledbCommand;<o:p>
<o:p>
termDA.Fill(termDS, "Ssp_SRS_GetAdvisingTerms");<o:p>
Connection.Close();<o:p>
<o:p>
}<o:p>
catch(Exception e)<o:p>
{<o:p>
CloseDatabaseOnError();<o:p>
throw new AdvisingTermNotReadException(e);<o:p>
}<o:p>
return termDS ;<o:p>
}<o:p>
<o:p>
<o:p>
}<o:p>
<o:p>
<o:p>
// AdvisingTermNotReadException occurs when there is an error //while reading the <o:p>
// advising terms from the database.<o:p>
[Serializable]<o:p>
public class AdvisingTermNotReadException : Exception<o:p>
{<o:p>
public AdvisingTermNotReadException(Exception ex) : <o:p>
base("Unable to get the advising term from the database. "+ex.Message , ex)<o:p>
{<o:p>
}<o:p>
<o:p>
public AdvisingTermNotReadException(SerializationInfo info, <o:p>
StreamingContext context) : base(info, context) <o:p>
{<o:p>
}<o:p>
}<o:p>
}<o:p>
<o:p>
<o:p>
<o:p>
2. buid.bat<o:p>
<o:p>
csc /target:library %DEBUGSAMPLE% /d:BuildBat /out:SRS.dll /r:System.EnterpriseServices.dll /r:System.dll /r:System.Data.dll *.cs<o:p>
<o:p>
regsvcs SRS.dll<o:p>
gacutil -i SRS.dll<o:p>
<o:p>
@echo.<o:p>
@echo To uninstall the Transactions Sample, run "build -u"<o:p>
@echo.<o:p>
<o:p>
@goto exit<o:p>
<o:p>
:clean<o:p>
gacutil /u SRS,PublicKeyToken=b7073b6138b34cac<o:p>
regsvcs /u SRS.dll<o:p>
<o:p>
:exit<o:p>
<o:p>
<o:p>
3. frmTerm.cs use the Component<o:p>
<o:p>
<o:p>
private void Button_Click(
object sender, System.EventArgs e
)<o:p>
{<o:p>
Using(SRS.Term _Term = new SIS.Term())<o:p>
{<o:p>
DataSet DSTerm = new DataSet();<o:p>
DSTerm = _Term.GetAdvisingTerms()<o:p>
<o:p>
//To retrieve the data<o:p>
int i;<o:p>
i = DSTerm.Tables.Rows.Count;<o:p>
while(i > 0)<o:p>
{<o:p>
Response.Write(DSTerm.Tables.Rows[i-1][“Term_Desc”].ToString());<o:p>
}<o:p>
}<o:p>
}
<o:p>
<o:p>
Reference: Microsoft .Net Help<o:p>
<o:p>