Hi while testing my Business objects I came acroos an error with the Transactional(TransactionalTypes.TransactionScope) on my Insert DataPortal method. The error returned is "Communication with underlining transaction manager failed."
In my code you will see a call out to a command class called "Exist". That makes a call to the database without the Transaction attribute. After it returns, I continue with the transactional call and on the cn.open statement is where the process abends.
Anyone have a clue to why this happens? I've done this before and never had an issue. In VB.NET or C#.
I've included the code for bouth methods here;
==================================================================================
/// <summary>
///
/// </summary>
[Transactional(TransactionalTypes.TransactionScope)]
protected override void DataPortal_Insert()
{
{
//Turn off error flag and clear message value
_Error = false;
_ErrorMessage = string.Empty;
if (IsNew)
{
if (Exists(_TableCode))
{
_CheckOk = false;
_Error = true;
_ErrorMessage = string.Concat("Table Code: ", _TableCode, " currently exit in the database");
return;
}
else
{
_CheckOk = true;
}
}
if (base.IsDirty)
{
try
{
using (SqlConnection cn = new SqlConnection(Database.ConnectionString))
{
cn.Open();
using (SqlCommand cm = cn.CreateCommand())
{
cm.CommandText = "[Security].[up_Add_TableCode_By_ID]";
{
string tmpUser = null;
try
{
//Get the current logged in users name
tmpUser = Csla.ApplicationContext.User.Identity.Name;
{
cm.CommandType = CommandType.StoredProcedure;
cm.Parameters.AddWithValue("@Codeid", _CodeID);
cm.Parameters.AddWithValue("@TableCode", _TableCode);
cm.Parameters.AddWithValue("@Description", _Description);
cm.Parameters.AddWithValue("@RecordActive", _RecordActive);
SqlParameter param = new SqlParameter("@newLastChanged", SqlDbType.Timestamp);
param.Direction = ParameterDirection.Output;
cm.Parameters.Add(param);
cm.Parameters.AddWithValue("@User", tmpUser);
cm.Parameters.AddWithValue("@Process", _Process);
cm.ExecuteNonQuery();
_RecordTimestamp = (byte[])cm.Parameters["@newLastChanged"].Value;
}
}
catch (SqlException ax)
{
_Error = true;
_ErrorMessage = ax.Message;
}
catch (Csla.DataPortalException ex)
{
_Error = true;
_ErrorMessage = ex.Message;
}
}
}
}
_CheckOk = true;
}
catch (Csla.DataPortalException ex)
{
_Error = true;
_ErrorMessage = ex.Message;
}
}
// update child objects
FieldManager.UpdateChildren(this);
}
}
===================================================================================
public static bool Exists(string
pCode)
{
ExistsCommand result = DataPortal.Execute<ExistsCommand>(new ExistsCommand
(pCode));
return
result.Exists;
}
///
<summary>
///
///
</summary>
[
Serializable
()]
private class ExistsCommand :
CommandBase
{
private string
_Code;
private bool
_Exists;
///
<summary>
///
///
</summary>
public bool
Exists
{
get { return
_Exists; }
}
///
<summary>
///
///
</summary>
///
<param name="pcode"></param>
public ExistsCommand(string
pcode)
{ _Code = pcode; }
///
<summary>
///
///
</summary>
protected override void
DataPortal_Execute()
{ {
using (SqlConnection cn = new SqlConnection(Database
.ConnectionString))
{ cn.Open();
using (SqlCommand
cm = cn.CreateCommand())
{ cm.CommandType =
CommandType
.Text;
cm.CommandText =
"SELECT Count(*) FROM [Security].[TableCode] WHERE Code_Name = @Code"
;
cm.Parameters.AddWithValue(
"@Code"
, _Code);
int count = (int
)cm.ExecuteScalar();
Ok, I found an answer to this problem. Here's the link to the post that fixed my problem,
Hi,
Is there any reason why you are no using the ConnectionManager class:
using (var cnn = ConnectionManager<SqlConnection>.GetManager("DB:Something"))
{
// Do connection stuff here.
}
This will help you avoid escalating the transaction to the point where you need to use the enterprise services (MSDTC ).
Copyright (c) Marimer LLC