Should I use transacion scope in a shared hosting server? - asp.net

Suppose I have to different methods and I place them in the transaction scope.
But every method open it's connection. so I need to enable MSDTC service in windows server.
but it is a shared hosting server and i can not enable it.
class Debit
{
public void InsertA()
{
//InsertCode
}
}
class Credit
{
public void InsertB()
{
// InsertCode
}
}
using (TransactionScope ts = new TransactionScope(TransactionScopeOption.Required))
{
DebitBAL debit = new DebitBAL();
CreditBAL credit = new CreditBAL();
debit.InsertA();
credit.InsertB();
ts.complete();
}
I use entity framework for my statements.
is it a good idea using transaction scope in a shared hosting server?

See this link for how to use transaction scopes with entity framework
In this link , explained for three cases in which transaction scope is being used to show rollback when an error occurs during an update of multiple entities:
1: when you have multiple save calls to the context;
2: when you have single save with multiple object;
3: and transactions across multiple contexts.

Related

Include scheduling in web-application in asp.net

I wanted to run scheduling process in asp.net periodically in web application.
In brief,My database table is having date & deadline Hrs.I want to calculate expected dateTime from both then another table get updated (inserts 1000s of records) periodically & also want to run process of mail sending according to that calculation for the same.
This is expected scheduled process which should be executed periodically.
The Quartz.NET job scheduler library is excellent for this sort of thing.
You can use Window Service to work in backgroud or scheduling , please see below links:
Using Timers in a Windows Service
Here's what I did:
public class Email {
private static System.Threading.Timer threadingTimer;
public static void StartTimer()
{
if (threadingTimer == null)
threadingTimer = new Timer(new TimerCallback(Callback), HttpContext.Current, 0, 20000);
}
private static void Callback(object sender)
{
if (/* Your condition to send emails */)
using (var context = new MyEntities())
{
var users = from user in context.Usere
select user;
foreach (var user in users)
{
// Send an email to user
}
}
}
}
And you have to add this to Application_Start:
void Application_Start(object sender, EventArgs e)
{
EMail.StartTimer();
}
Check out this old article from Jeff Atwood:
Easy Background Tasks in ASP.NET
Basically he suggests that you use the cache expiration mechanism to schedule a timed task. The problem is: your web application needs to be running. What if the website isn't called at all? Well, since IIS 7.5 there is the possibility to keep your web app running at all times: auto starting web apps. Jeff suggests in the comments that his approach served well until they outgrew it. His conclusion is that for small sites this is a good approach.

How to get HealthVault to work with multiple ApplicationID in same application

We may never know why Microsoft decided to limit developers by making HealthVault applications constrained to a single web/app.config entry for a HealthVault application. However I need to be able to make 2 (or more) HealthVault ApplicationID’s work with one ASP.NET website? I’m looking for an effective and reliable way to do this.
I won’t go into the details of the reasoning behind 2 different HealthVault applications, but other than to say we need it to work. I still cannot login correctly with MSDN Forums (think infinite redirection sign in loop) so I am hoping for a post here that will help me.
I did contact a HealthVault developer on how to achieve this however the developer gave a suggestion that I don’t believe would be reliable (if I’m wrong let me know).
The developer’s suggestion was to do the following in code when you needed to connect to HealthVault, but prior to connecting:
ConfigurationSettings.AppSettings[“ApplicationId”] = “[YOUR APP ID]”;
The problem is that this is a static property and I do see this as an issue as our web application will have different users accessing both HealthVault applications at the same time.
Does anyone have any suggestions to make 2 (or more) HealthVault ApplicationID’s work with one ASP.NET website? I’m looking for an effective and reliable way to do this.
There is a way to dynamically switch app ids on runtime. Both applications must be created, both certificates must be installed. Few things to keep in mind. For every authenticated connection, user will be granted a token (aka wctoken). This token is consumed when user is redirect back from Live ID (in case live id is used...) by your redirect.aspx page (assuming your redirect page inherits from HealthServiceActionPage.This means that everytime you switch applications, you must redirect user back to Live ID with new app id to receive new token.
Here is code sample that can be user to dynamically change settings:
public class ConfigurationManager : HealthWebApplicationConfiguration
{
private string appid;
public ConfigurationManager(string appid)
{
this.appid = appid;
}
public override Guid ApplicationId
{
get
{
return AppManager.Current.GetCurrentAppId(this.appid);
}
}
}
public class AppManager
{
private static readonly Object lck = new Object();
public Guid? App;
public static AppManager Current
{
get
{
AppManager mgr = null;
if (_current == null)
{
lock (lck)
{
mgr = new AppManager();
}
}
return mgr;
}
}
private static AppManager _current;
public Guid GetCurrentAppId(string id)
{
return new Guid(id);
}
}
Usage:
ConfigurationManager cm = new ConfigurationManager(your-app-id-here);
HealthWebApplicationConfiguration.Current = cm;

Entity Framework reverting changes

I am develloping a web form that has a wizard with 4 steps:
On each step I'me creating new entities generated from a database.
The problem is that being a wizzard, the user can change the properties of the controls that will originate the values to be stored.
So I need to release the created entity objects or return that entity values to the original rows stored on the database.
How can I do this.
Should'n it work if I set each created entity object to null?
By the way this is how I'm doing it:
entities = new Entities();
...
Client client = new Client();
client.name = tbxName.text
...
entities.SaveChanges();
entities.Connection.Close();
So If this code is executed on the 2nd wizard part of a wizard of 3 parts and I go back and fowrward through this set more the once the client creating runs more than once, so there's my problem.
So how can I unCreate it :-P
Thannks!!!
If you are building wizard you must manage it as single operation. It means that you have to store built entity graph in the session and save it only if whole wizard is completed and confirmed. Your step logic also must check if related data are already present in the entity graph and use them instead of creating new one.
If your using Entity Framework, why not implement the Unit Of Work pattern? Each part of your wizard builds the UoW and the "final step" commits the unit of work.
There was an article called "The Unit Of Work Pattern And Persistence Ignorance" in MSDN magazine a few years ago that explains the concept.
This is the way I do it:
1- Create a place where you can manage your Session variables :
public class SessionObjects { }
2- I save my ObjectContext in the Session so I create a property to manage it in the mentioned class :
public static ObjectContextEntities ObjectContextEntities
{
get
{
return (ObjectContextEntities)HttpContext.Current.Session["ObjectContextEntities"];
}
set
{
HttpContext.Current.Session["ObjectContextEntities"] = value;
}
}
3- Initialize the ObjectContext on the wizard's start and dispose it on its end:
void StartWizard()
{
SessionObject.ObjectContextEntities = new ObjectContextEntities();
}
void StartWizard()
{
SessionObject.ObjectContextEntities = new ObjectContextEntities();
}
void EndWizard()
{
((ObjectContextEntities)SessionObject.ObjectContextEntities).Dispose();
}
4- To save wizard result to the database you can call:
void SaveWizard()
{
((ObjectContextEntities)SessionObject.ObjectContextEntities).SaveAllChanges();
}
5- To reset wizard simply call EndWizard then StartWizard .
I guess you know how to manage your ObjectEntity objects and in the ObjectContext so you can continue from here by your self ..

Access SQLite from different processes

I'm developing an application that uses SQLite as the primary data storage method. I have two processes running for my app using an alternate entry point.
I need to access the same DB from the two different processes but as we all now SQLite is not like a server DB engine, it can only be accessed once at a time.
I wanted to know if there is a way to kind of "lock" the DB when it's being accessed by other process so that if the second process tries to acces the DB at the same time, it would wait until the first process finishes and then try to access it again.
How can this issue be treated?
If you have not already, create a class that abstracts your database access out and store it in the RuntimeStore. From wherever you are going to interface with SQLite, get a reference to that class using the GUID you stored it with (RuntimeStore.get(long)) and synchronize the class however you would normally (member object lock, synchronized methods).
Do NOT just use the Wikipedia style singleton pattern as it is not a true singleton across processes on this platform.
See:
http://www.blackberry.com/developers/docs/5.0.0api/net/rim/device/api/system/RuntimeStore.html
Sample:
class SQLManager {
private static long GUID = 0xa178d3ce564cae69L; // hash of com.stackoverflow.SQLManager
private SQLManager() {
// ctor stuff here
}
public static SQLManager getInstance() {
RuntimeStore rs = RuntimeStore.getRuntimeStore();
SQLManager instance = rs.get(GUID);
if (instance == null) {
instance = new SQLManager();
rs.put(GUID, instance);
}
return instance;
}
}
You're still using the singleton "pattern" per se, but you're storing the object instance in the RuntimeStore on first getInstance call, and subsequently pulling it form the RuntimeStore - using a GUID that you specify.

Will transactionscope work over multiple calls to different services?

I'm writing some merge functionality in C# asp.NET MVC2. I am also using using Linq2SQL.
I have a block of code which calls two services, MessageService and UserService. These both in term call their appropriate repositories and make the amendments to the db. Each repository declares it's own instance of the repository so I'm thinking this will escalate the following code to DTC . The code is called from the AccountService, is this going to work at this level? And also is it bad practise to declare the DataContext at the top of every repository or should I pass the object around somehow? Thank you in advance
//Run the merge
try
{
using (TransactionScope scope = new TransactionScope())
{
// Update Messages to be owned by primary user
if (!_MessageService.UpdateCreatedById(MergeUser.UserID, CoreUser.UserID))
{
return false;
}
// Update Comments to be owned by primary user
foreach (var curComment in _MessageService.GetUserComments(MergeUser.UserID))
{
curComment.CreatedBy = CoreUser.UserID;
}
_MessageService.Save();
// Update Logins to be owned by primary user
foreach (var CurLogin in _UserService.GetLogins(MergeUser.UserID))
{
CurLogin.UserID = CoreUser.UserID;
}
_UserService.Save();
scope.Complete();
}
return true;
}
catch (Exception ex)
{
_ErrorStack.Add(ex.Message);
ErrorService.AddError(new ErrorModel("Portal", "WidgetRepository", ErrorHelper.ErrorTypes.Critical, ex));
return false;
}
Yes, This will work. TransactionScope leverages the Distributed transaction coordinator so it's capable of hosting Transactions beyond database levels.
Recommended practice for DataContext lifecycle is to restrict it to a unit-of-work.
I have two constructors on my repositories, one that takes a data context and one that does not (which then instatiates it's own). This means that I can create repositories using a shared data context as required.
My service classes then take a repository object in their constructor, so I can instantiate several services using repositories that are sharing a data context, if so required.

Resources