Using S2Tx.NET, it is possible to apply an Aspect to manage transaction to a .NET object. Refer to Warnings before applying an aspect. S2Container.NET supports System.Transactions (.NET 2.0 or higher), local transaction, and MS DTC (Microsoft Distributed Transaction Coordinator). Following are transaction attributes available:
To use local transaction, retrieve a connection from Seasar.Extension.Tx.Impl.TxDataSource. DAO (Data Access Object) is not used because Advice(MethodInterceptor) manages opening and closing connections.
Property of type Seasar.Extension.ADO.IDataSource is used to inject TxDataSource into DAO.
Connection, transaction, command, parameter are created from dataSource. Following is an example of DAO interface and DAO implementation class.
EmployeeDao.cs
C#
using System;
using System.Data;
using Seasar.Extension.ADO;
namespace Seasar.Examples.Reference.LocalTx
{
// DAO interface to use EMPpublicinterface IEmployeeDao
{
void Insert();
}
// DAO implementation class to use EMPpublicclass EmployeeDaoImpl : IEmployeeDao
{
private IDataSource dataSource;
// property to inject TxDataSourcepublic IDataSource DataSource
{
set { dataSource = value; }
}
#region IEmployeeDao member
publicvoid Insert()
{
string sql = "insert into emp2 values(@empno, @ename, @deptnum)";
using(IDbCommand cmd = dataSource.GetCommand(sql,
dataSource.GetConnection(), dataSource.GetTransaction()))
{
cmd.Parameters.Add(dataSource.GetParameter("@empno", 99));
cmd.Parameters.Add(dataSource.GetParameter("@ename", "Sugimoto"));
cmd.Parameters.Add(dataSource.GetParameter("@deptnum", 31));
cmd.ExecuteNonQuery();
Console.WriteLine("Inserted employee");
}
}
#endregion
}
}
VB.NET
Imports System
Imports System.Data
Imports Seasar.Extension.ADO
Namespace Seasar.Examples.Reference.LocalTx
' DAO interface to use EMPPublicInterface IEmployeeDao
Sub Insert()
EndInterface'IEmployeeDao' DAO implementation class to use EMPPublicClass EmployeeDaoImpl
Implements IEmployeeDao
Private dataSource As IDataSource
' property to inject TxDataSourcePublicWriteOnlyProperty DataSource() As IDataSource
Set(ByVal value As IDataSource)
dataSource = value
EndSetEndPropertyPublicSub Insert()
Dim sql AsString = "insert into emp2 values(@empno, @ename, @deptnum)"Dim cmd As IDbCommand = dataSource.GetCommand(sql, _
dataSource.GetConnection(), dataSource.GetTransaction())
Try
cmd.Parameters.Add(dataSource.GetParameter("@empno", 99))
cmd.Parameters.Add(dataSource.GetParameter("@ename", "Sugimoto"))
cmd.Parameters.Add(dataSource.GetParameter("@deptnum", 31))
cmd.ExecuteNonQuery()
Console.WriteLine("Inserted employee")
Finally
cmd.Dispose()
EndTryEndSubEndClassEndNamespace
Class to executeIEmployeeDao
LocalTxClient.cs
C#
using System;
using Seasar.Framework.Container;
using Seasar.Framework.Container.Factory;
namespace Seasar.Examples.Reference.LocalTx
{
publicclass LocalTxClient
{
privatestaticreadonly String PATH
= "Seasar.Examples/Reference/LocalTx/LocalTxClient.dicon";
public LocalTxClient() {}
publicvoid Main()
{
// create S2Container
IS2Container container = S2ContainerFactory.Create(PATH);
// initialize S2Container
container.Init();
// retrieve component to implement IEmployeeDao from S2Container
IEmployeeDao dao = (IEmployeeDao) container.GetComponent(typeof(IEmployeeDao));
// insert employee
dao.Insert();
}
}
}
VB.NET
Imports System
Imports Seasar.Framework.Container
Imports Seasar.Framework.Container.Factory
Namespace Seasar.Examples.Reference.LocalTx
PublicClass LocalTxClient
PrivateShared PATH As [String] = _
"Seasar.Examples/Reference/LocalTx/LocalTxClient.dicon"PublicSubNew()
EndSubPublicSub Main()
' create S2ContainerDim container As IS2Container = S2ContainerFactory.Create(PATH)
' initialized S2Container
container.Init()
' retrieve component to implement IEmployeeDao from S2ContainerDim dao As IEmployeeDao = _
CType(container.GetComponent(GetType(IEmployeeDao)), IEmployeeDao)
' insert employee
dao.Insert()
EndSubEndClassEndNamespace
Following is an example of a dicon file. To apply Required attribute transaction, aspect in EmployeeDaoImpl is set to LocalTx.Required.
MS DTC must be properly setup before using MS DTC. When MS DTC is used, connection do not have to be retrieved from TxDataSource, but to write source code that is not dependent on a data provider, connection, command, and parameter objects are created from Seasar.Extension.ADO.Impl.DataSourceImpl.
When MS DTC is used, a transaction is maintained even if a connection is closed after each query.
Following is an example of DAO interface and DAO implementation class.
EmployeeDao.cs
C#
using System;
using System.Data;
using Seasar.Extension.ADO;
namespace Seasar.Examples.Reference.DTCTx
{
// DAO interface to use EMPpublicinterface IEmployeeDao
{
void Insert();
}
// DAO implementation class to use EMPpublicclass EmployeeDaoImpl : IEmployeeDao
{
private IDataSource dataSource;
// property to inject DataSourceImplpublic IDataSource DataSource
{
set { dataSource = value; }
}
#region IEmployeeDao member
publicvoid Insert()
{
using(IDbConnection cn = dataSource.GetConnection())
{
cn.Open();
string sql = "insert into emp2 values(@empno, @ename, @deptnum)";
using(IDbCommand cmd = dataSource.GetCommand(sql,cn))
{
cmd.Parameters.Add(dataSource.GetParameter("@empno", 99));
cmd.Parameters.Add(dataSource.GetParameter("@ename", "Sugimoto"));
cmd.Parameters.Add(dataSource.GetParameter("@deptnum", 31));
cmd.ExecuteNonQuery();
Console.WriteLine("inserted employee");
}
}
}
#endregion
}
}
VB.NET
Imports System
Imports System.Data
Imports Seasar.Extension.ADO
Namespace Seasar.Examples.Reference.DTCTx
' DAO interface to use EMPPublicInterface IEmployeeDao
Sub Insert()
EndInterface' DAO implementation class to use EMPPublicClass EmployeeDaoImpl
Implements IEmployeeDao
Private dataSource As IDataSource
' property to inject DataSourceImplPublicWriteOnlyProperty DataSource() As IDataSource
Set(ByVal value As IDataSource)
dataSource = value
EndSetEndPropertyPublicSub Insert()
Dim cn As IDbConnection = dataSource.GetConnection()
Try
cn.Open()
Dim sql AsString = "insert into emp2 values(@empno, @ename, @deptnum)"Dim cmd As IDbCommand = dataSource.GetCommand(sql, cn)
Try
cmd.Parameters.Add(dataSource.GetParameter("@empno", 99))
cmd.Parameters.Add(dataSource.GetParameter("@ename", "Sugimoto"))
cmd.Parameters.Add(dataSource.GetParameter("@deptnum", 31))
cmd.ExecuteNonQuery()
Console.WriteLine("inserted employee")
Finally
cmd.Dispose()
EndTryFinally
cn.Dispose()
EndTryEndSubEndClassEndNamespace
Class to execute IEmployeeDao is as follows:
DTCTxClient.cs
C#
using System;
using Seasar.Framework.Container;
using Seasar.Framework.Container.Factory;
namespace Seasar.Examples.Reference.DTCTx
{
publicclass DTCTxClient
{
privatestaticreadonly String PATH
= "Seasar.Examples/Reference/DTCTx/DTCTxClient.dicon";
public DTCTxClient() {}
publicvoid Main()
{
// create S2Container
IS2Container container = S2ContainerFactory.Create(PATH);
// initialize S2Container
container.Init();
// retrieve component to implement IEmployeeDao from S2Container
IEmployeeDao dao = (IEmployeeDao) container.GetComponent(typeof(IEmployeeDao));
// inserted employee
dao.Insert();
}
}
}
VB.NET
Imports System
Imports Seasar.Framework.Container
Imports Seasar.Framework.Container.Factory
Namespace Seasar.Examples.Reference.DTCTx
PublicClass DTCTxClient
PrivateShared PATH As [String] = _
"Seasar.Examples/Reference/DTCTx/DTCTxClient.dicon"PublicSubNew()
EndSubPublicSub Main()
' create S2ContainerDim container As IS2Container = S2ContainerFactory.Create(PATH)
' initialize S2Container
container.Init()
' retrieve component to implement IEmployeeDao from S2ContainerDim dao As IEmployeeDao = _
CType(container.GetComponent(GetType(IEmployeeDao)), IEmployeeDao)
' insert employee
dao.Insert()
EndSubEndClassEndNamespace
Following is an example of a dicon file. To apply Required attribute transaction, aspect in EmployeeDaoImpl is set to DTCTx.RequiredTx.
Unlike in local transaction, connection do not have to be retrieved from TxDataSource, but to write source code that is not dependent on a data provider, connection, command, and parameter objects are created from Seasar.Extension.ADO.Impl.DataSourceImpl.
When System.Transactions is used, a transaction is maintained even if a connection is closed after each query.
Following is an example of DAO interface and DAO implementation class.
EmployeeDao.cs
C#
using System;
using System.Data;
using Seasar.Extension.ADO;
namespace Seasar.Examples.Reference.Tx
{
// DAO interface to use EMPpublicinterface IEmployeeDao
{
void Insert();
}
// DAO implementation class to use EMPpublicclass EmployeeDaoImpl : IEmployeeDao
{
private IDataSource dataSource;
// property to inject DataSourceImplpublic IDataSource DataSource
{
set { dataSource = value; }
}
#region IEmployeeDao member
publicvoid Insert()
{
using(IDbConnection cn = dataSource.GetConnection())
{
cn.Open();
string sql = "insert into emp2 values(@empno, @ename, @deptnum)";
using(IDbCommand cmd = dataSource.GetCommand(sql,cn))
{
cmd.Parameters.Add(dataSource.GetParameter("@empno", 99));
cmd.Parameters.Add(dataSource.GetParameter("@ename", "Sugimoto"));
cmd.Parameters.Add(dataSource.GetParameter("@deptnum", 31));
cmd.ExecuteNonQuery();
Console.WriteLine("inserted employee");
}
}
}
#endregion
}
}
VB.NET
Imports System
Imports System.Data
Imports Seasar.Extension.ADO
Namespace Seasar.Examples.Reference.Tx
' DAO interface to use EMPPublicInterface IEmployeeDao
Sub Insert()
EndInterface' DAO implementation class to use EMPPublicClass EmployeeDaoImpl
Implements IEmployeeDao
Private dataSource As IDataSource
' property to inject DataSourceImplPublicWriteOnlyProperty DataSource() As IDataSource
Set(ByVal value As IDataSource)
dataSource = value
EndSetEndPropertyPublicSub Insert()
Dim cn As IDbConnection = dataSource.GetConnection()
Try
cn.Open()
Dim sql AsString = "insert into emp2 values(@empno, @ename, @deptnum)"Dim cmd As IDbCommand = dataSource.GetCommand(sql, cn)
Try
cmd.Parameters.Add(dataSource.GetParameter("@empno", 99))
cmd.Parameters.Add(dataSource.GetParameter("@ename", "Sugimoto"))
cmd.Parameters.Add(dataSource.GetParameter("@deptnum", 31))
cmd.ExecuteNonQuery()
Console.WriteLine("inserted employee")
Finally
cmd.Dispose()
EndTryFinally
cn.Dispose()
EndTryEndSubEndClassEnd Namespace
Following is an example of a class to execute IEmployeeDao
TxClient.cs
C#
using System;
using Seasar.Framework.Container;
using Seasar.Framework.Container.Factory;
namespace Seasar.Examples.Reference.Tx
{
publicclass TxClient
{
privatestaticreadonly String PATH
= "Seasar.Examples/Reference/Tx/TxClient.dicon";
public TxClient() {}
publicvoid Main()
{
// create S2Container
IS2Container container = S2ContainerFactory.Create(PATH);
// initialize S2Container
container.Init();
// retrieve component to implement IEmployeeDao from S2Container
IEmployeeDao dao = (IEmployeeDao) container.GetComponent(typeof(IEmployeeDao));
// insert employee
dao.Insert();
}
}
}
VB.NET
Imports System
Imports Seasar.Framework.Container
Imports Seasar.Framework.Container.Factory
Namespace Seasar.Examples.Reference.Tx
PublicClass TxClient
PrivateShared PATH As [String] = _
"Seasar.Examples/Reference/Tx/TxClient.dicon"PublicSubNew()
EndSubPublicSub Main()
' create S2ContainerDim container As IS2Container = S2ContainerFactory.Create(PATH)
' initialize S2Container
container.Init()
' retrieve component to implement IEmployeeDao from S2ContainerDim dao As IEmployeeDao = _
CType(container.GetComponent(GetType(IEmployeeDao)), IEmployeeDao)
' insert employee
dao.Insert()
EndSubEndClassEndNamespace
Following is an example of a dicon file. To apply Required attribute transaction, aspect in EmployeeDaoImpl is set to Tx.RequiredTx.
Ado.dicon and execution result are the same as those in local transaction
S2Container.NET by default provides Tx.dicon, LocalTx.dicon, and DTCTx.dicon (s2container.net/source/Seasar.Tests). It is only necessary to set component name of an Advice to an aspect tag.