 |
BOOK: ASP.NET 2.0 Website Programming Problem Design Solution ISBN: 978-0-7645-8464-0  | This is the forum to discuss the Wrox book ASP.NET 2.0 Website Programming: Problem - Design - Solution by Marco Bellinaso; ISBN: 9780764584640 |
|
Welcome to the p2p.wrox.com Forums.
You are currently viewing the BOOK: ASP.NET 2.0 Website Programming Problem Design Solution ISBN: 978-0-7645-8464-0 section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
|
|
|
|
|

February 6th, 2008, 05:50 AM
|
|
Friend of Wrox
|
|
Join Date: Mar 2007
Posts: 488
Thanks: 2
Thanked 11 Times in 10 Posts
|
|
Quote:
quote:Originally posted by forumuser
not very viable in anyone's book i'd have thought.
|
a not very 'bright' way to implement concurrency control would be to have an 'inUse' boolean flag on the parent row. this would be set to true by the 1st editor and would be queried as part of the process of opening for editting. however, this simplistic approach is easily defeated if for example the 1st eidtor just closes her browser, rather than cancel etc...
i'd be interested to see what schemes folks are using out there (or have envisaged) as these areas really are the make or break when scaling up. 95% of what's needed is there (plus using a templated approach, can be implemented to a known standard) in the original tbh, it's just a matter of identifying good reusable patterns for the concurrency and exception handling (as well as logging). there are of course case by case 'additions' that each site may require (for example, bandwidth checks on highly trafficed media sites etc) but these are outside the 'black-box' requirement to elevate the core to 98%.
let's see if we can work this out now :D
jimi
http://www.originaltalent.com
|
|

February 6th, 2008, 06:48 AM
|
|
Friend of Wrox
|
|
Join Date: Mar 2007
Posts: 488
Thanks: 2
Thanked 11 Times in 10 Posts
|
|
actually, just had a thought (while sitting on the loo, like most of my 'best' thoughts!!). perhaps rather than using an 'inUse' flag, a better idea would be to have a column 'sessionID' on the parent row. this column would start out 'null' and would be queried prior to editing. if it was 'null', then the user would be allowed to edit the row and thier 'sessionID' would be updated into the row. subsequent users wishing to edit the row would 'find' this sessionID in the parent row column and the system would determine if the session was still active. if the session was still active, then the edit would be disallowed. if the session was inactive (i.e. browser had been closed or user had allowed session to exprire whilst editing), then that 'new' user would update the sessionID with their sessionID and take control of the lock on that row. on finishing editing legally (i.e. cancel or save), the sessionID column would be set to 'null'.
a simplistic view on it, but a 1st stab. of course, then the issue of web farms comes into the equation, but let's see what the pitfalls of this approach on a single cpu throws up 1st.
[edit] re the webfarms sessionid's. anyone know how to find out the different sessions running across different farms from a single point of entry?? (don't let thinking about this interfere with the main idea above)
jimi
http://www.originaltalent.com
|
|

February 6th, 2008, 07:33 AM
|
|
Authorized User
|
|
Join Date: Jun 2006
Posts: 46
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Thanks Lee Dumond for answering my queries!
forumuser, why don't you share with us the changes you made in flixon templates :P
|
|

February 6th, 2008, 07:51 AM
|
|
Friend of Wrox
|
|
Join Date: Mar 2007
Posts: 488
Thanks: 2
Thanked 11 Times in 10 Posts
|
|
ooops - wrong post
|
|

February 6th, 2008, 10:52 AM
|
 |
Wrox Author
|
|
Join Date: Jan 2008
Posts: 923
Thanks: 12
Thanked 166 Times in 162 Posts
|
|
Jimibt,
If you're interested in implementing optimistic concurrency, the classic way would be to compare all values with the original values during each round trip to the server. However, in my opinion, the easiest way to implement concurrency control here would be through the use of timestamp columns (which is actually along the lines of your idea).
The advantage here is that SQL Server will automatically update the value of a column of type timestamp every time any value in the row has changed. The idea would be to pull the timestamp column during Select, then compare it to the current value on Updates.
There is a pretty good tutorial on it here:
http://www.primedigit.com/implementi...ql-timestamps/
|
|

February 6th, 2008, 12:12 PM
|
|
Friend of Wrox
|
|
Join Date: Mar 2007
Posts: 488
Thanks: 2
Thanked 11 Times in 10 Posts
|
|
lee,
sounds interesting. the only 'downside' (for want of a better word) is that you're not going to know if someone is in 'edit' mode when you grab the timestamp field. therefore, you could spend a long time on a lengthy edit, only to find that you'd be unable to save it as it had changed since you went into edit with it. but with a little thought and redesign, i think something in this ballpark will work. just a matter of figuring how to safely tinker with the timestamp field with both the app and allowing sqlserver to do it 'naturally'.
keep the thoughts coming..
jimi
http://www.originaltalent.com
|
|

February 6th, 2008, 03:33 PM
|
 |
Wrox Author
|
|
Join Date: Jan 2008
Posts: 923
Thanks: 12
Thanked 166 Times in 162 Posts
|
|
Quote:
quote:Originally posted by jimibt
lee,
sounds interesting. the only 'downside' (for want of a better word) is that you're not going to know if someone is in 'edit' mode when you grab the timestamp field. therefore, you could spend a long time on a lengthy edit, only to find that you'd be unable to save it as it had changed since you went into edit with it.
|
Well, of course, that's the risk you take with optimistic concurrency. I still think it's better than what you have now, which is no concurrency at all. At least you have a chance to inform the user that his update isn't accepted, and why. It would certainly encourage the user to perform frequent saves, which they should be doing anyway.
The only way around that is to implement pessimistic concurrency, where you would "lock" a record when a user accesses it for updating, thereby preventing any concurrent users from editing or deleting that record until the first user commits their update.
This presents a whole other set of issues. Locking records can be tricky, especially in on the Web, which by its nature is a "disconnected" environment. And consider this -- if a lock is not properly relinquished, it prevents other users from updating data. Let's say an Editor starts updating an article, and then walks away from their browser for a few hours (or a few days). No other user will be able to update that record until the original user returns and completes his update. This means you are going to have to figure in some sort of "timeout" mechanism to cancel the lock.
Again, it depends on the needs of the application, and the level of sophistication you want to implement. I think optimistic concurrency would be a good start, and probably not that hard to do.
|
|

February 7th, 2008, 05:19 AM
|
|
Authorized User
|
|
Join Date: Nov 2007
Posts: 76
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
timestamp?
tectrix, here's an example of what i mean:
/// <summary>
/// Returns a collection with all <%= provider.Tables[i].TableName %>
/// </summary>
public override List<<%= provider.Tables[i].TableNameNoPrefix %>Entity>Get<%= provider.Tables[i].TableNameNoPrefix %>(string sortExpression, int startRowIndex, int maximumRows)
{
try
{
using (SqlConnection cn = new SqlConnection(ConnectionString))
{
SqlCommand cmd = new SqlCommand("up_<%= provider.Tables[i].TableNameNoPrefix %>GetAll", cn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@startRowIndex", SqlDbType.Int).Value = startRowIndex;
cmd.Parameters.Add("@maximumRows", SqlDbType.Int).Value = startRowIndex + maximumRows;
cmd.Parameters.Add("@sortExpression", SqlDbType.NVarChar).Value = sortExpression;
cn.Open();
return Get<%= provider.Tables[i].TableNameNoPrefix %>CollectionFromReader(ExecuteReader(cmd));
}
}
catch (SqlException e)
{
CommonFunctions.LogError(e.Message, (int) Enums.Table.<%= provider.Tables[i].TableName %>);
return null;
}
catch (Exception ex)
{
CommonFunctions.LogError(ex.Message, (int) Enums.Table.<%= provider.Tables[i].TableName %>);
return null;
}
}
|
|

February 7th, 2008, 02:47 PM
|
|
Authorized User
|
|
Join Date: Jun 2006
Posts: 46
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
forumuser,does the health monitoring system of TBH not already logging SQL exceptions?
Oh... I'm confused! Lee Dumond you said there is no Exception Handling in TBH. The health monitoring system of TBH logs most of the application exceptions. Guys, please clear me one thing, what exactly we mean when we say "Exception Handling"? Writing up the code within Try block,catching the expected exceptions and then logging them up... is it all about exception handling?
If I write my mail sending code within try block,everything goes fine, I tell the user mail has been send and if mail is not send,I display an error msg within the catch block.. am I doing "exception handling"?
Sorry guys for hijacking this thread!
|
|

February 7th, 2008, 06:45 PM
|
 |
Wrox Author
|
|
Join Date: Jan 2008
Posts: 923
Thanks: 12
Thanked 166 Times in 162 Posts
|
|
Quote:
quote:Originally posted by tectrix
forumuser,does the health monitoring system of TBH not already logging SQL exceptions?
Oh... I'm confused! Lee Dumond you said there is no Exception Handling in TBH. The health monitoring system of TBH logs most of the application exceptions. Guys, please clear me one thing, what exactly we mean when we say "Exception Handling"? Writing up the code within Try block,catching the expected exceptions and then logging them up... is it all about exception handling?
|
Exception handling is about a lot more than logging errors. Logging exceptions isn't "handling" -- it's just writing it down.
Quote:
quote:Originally posted by tectrix
If I write my mail sending code within try block,everything goes fine, I tell the user mail has been send and if mail is not send,I display an error msg within the catch block.. am I doing "exception handling"?
Sorry guys for hijacking this thread!
|
Basically, exception handling means to do something with an error rather than just letting it bubble up to the UI unhandled. So, in the example above, you're in fact doing exception handling. Without the try-catch, if the smtp server is down, the user is gonna get a big fat cryptic server error. That's what you want to avoid.
But the most important place to implement exception handling is not just in the UI (as above) but in the DAL and BLL, and that's where TBH comes up short. Ever notice there are no try-catch blocks in the provider classes? In any data-intensive application, server timeouts or the DB just being down is a real possibility from time to time. The idea that forumuser has in his example is a start. But all he's doing is logging the exception. Ideally, you'd want to catch the exception in the DAL, log it, then rethrow it and catch it again in the BLL, then show the user a nice message in the UI like "There was an error processing your request. Please try again" or something like that.
Does this make sense?
|
|
 |