Access SQLite from different processes - sqlite

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.

Related

EF Core Update with List

To make updates to a record of SQL Server using Entity Framework Core, I query the record I need to update, make changes to the object and then call .SaveChanges(). This works nice and clean.
For example:
var emp = _context.Employee.FirstOrDefault(item => item.IdEmployee == Data.IdEmployee);
emp.IdPosition = Data.IdPosition;
await _context.SaveChangesAsync();
But is there a standard method if I want to update multiple records?
My first approach was using a list passing it to the controller, but then I would need to go through that list and save changes every time, never really finished this option as I regarded it as not optimal.
For now what I do is instead of passing a list to the controller, I pass each object to the controller using a for. (kind of the same...)
for(int i = 0; i < ObjectList.Count; i ++)
{
/* Some code */
var httpResponseObject = await MyRepositories.Post<Object>(url+"/Controller", Object);
}
And then do the same thing on the controller as before, when updating only one record, for each of the records...
I don't feel this is the best possible approach, but I haven't found another way, yet.
What would be the optimal way of doing this?
Your question has nothing to do with Blazor... However, I'm not sure I understand what is the issue. When you call the SaveChangesAsync method, all changes in your context are committed to the database. You don't have to pass one object at a time...You can pass a list of objects
Hope this helps...
Updating records in bulk using Entity Framework or other Object Relational Mapping (ORM) libraries is a common challenge because they will run an UPDATE command for every record. You could try using Entity Framework Plus, which is an extension to do bulk updates.
If updating multiple records with a single call is critical for you, I would recommend just writing a stored procedure and call if from your service. Entity Framework can also run direct queries and stored procedures.
It looks like the user makes some changes and then a save action needs to persist multiple records at the same time. You could trigger multiple AJAX calls—or, if you need, just one.
What I would do is create an endpoint—with an API controller and an action—that's specific to your needs. For example, to update the position of records in a table:
Controller:
/DataOrder
Action:
[HttpPut]
public async void Update([FromBody] DataChanges changes)
{
foreach(var change in changes)
{
var dbRecord = _context.Employees.Find(change.RecordId);
dbRecord.IdPosition = change.Position;
}
_context.SaveChanges();
}
public class DataChanges
{
public List<DataChange> Items {get;set;}
public DataChangesWrapper()
{
Items = new List<DataChange>();
}
}
public class DataChange
{
public int RecordId {get;set;}
public int Position {get;set;}
}
The foreach statement will execute an UPDATE for every record. If you want a single database call, however, you can write a SQL query or have a stored procedure in the database and pass the data as a DataTable parameter instead.

Oracle Coherence - retrieving specific Member using Key

I have used Partitioned scheme and used data-affinity to store related data together on Cluster member.
I am only interested to execute my Invocable on a subset of entire data. Can I find specific members storing subset of data I am interested in?
Currently I do this: partitionedService.getOwnershipEnabledMembers() which gets me all nodes running this service in cluster.
You can use PartitionedService.getKeyOwner(Object key)
You can use an EntryProcessor and execute it against the data that you want to process, eg.
public class MyProc extends AbstractProcessor implements Serializable
{
public Object process(Entry entry)
{
System.out.println("*** processing " + entry.getKey());
}
}
Now to run that, just:
cache.invokeAll(collKeys, new MyProc());
... where "collKeys" is a collection of keys to your cache, or:
cache.invokeAll(filter, new MyProc());
... where "filter" is a query on your cache.

static variable in asp.net web application

I have:
MyNameSpace.MyClass1
MyNameSpace.MyClass2
i need to get value from MyClass1.myvar1 from MyClass2.
Should I do that with static variable
What happens with variable value if it is static in a web application.
Im using MyClass1 as: var mClass=new MyNameSpace.MyClass1(), and from that im using mClass.
thank you
No, you should not use a static variable here. Remember, static means the variable is global for the application. In ASP.Net, you have a single application instance that is shared among everyone who visits your site. Using static variables can result in one user seeing another user's data.
If the value context is global, than it is ok to use static variable. Remember that if the value is updated, its updated for all users. If the data is different or belong to a user, than never use static, instead instantiate object of MyClass1 inside MyClass2 method .
you can use following approach.
Declare MyClass1.myvar1 as public and access from MyClass2.
class MyClass1{
public int myvar1 = 7;
}
class MyClass2{
public void TestMethod(){
MyClass1 obj = new MyClass1();
int val = obj.myvar1;
}
}
In this case, your data is safe.
It is not OK to use a static variable within ASP.NET unless you take thread safety into account. A single request will generally run on a single thread. Different requests will probably run on different threads. (See http://blogs.msdn.com/b/tmarq/archive/2010/04/14/performing-asynchronous-work-or-tasks-in-asp-net-applications.aspx for some good threading information.)
Unless you study up on writing thread safe code, I would consider using the following objects instead to maintain static data:
Application - for application-wide static data
Session - if it's user specific static data
HttpContext.Items - if it's data to be used by different objects within a single request
HttpRuntime.Cache / HttpContext.Cache - to cache shared data that can have expirations / dependencies
All youneed is to make a new instance of your class2 and call your variable from created instance in class1 like
myclass1
{
string Variable = string.empty;
protected void YourMethod()
{
myclass2 c2 = new myclass2()
this.Variable = c2.Variable;
}
}

ASP.NET Object Caching in a Class

I'm trying to create a Caching Class to cache some objects from my pages. The purpose is to use the Caching system of the ASP.NET framework but to abstract it to separate class.
It seems that the caching doesn't persist.
Any ideas what I'm doing wrong here? Is it possible at all to cache object out side the Page it self?
EDIT: added the code:
Insert to cache
Cache c = new Cache();
c.Insert(userid.ToString(), DateTime.Now.AddSeconds(length), null, DateTime.Now.AddSeconds(length), Cache.NoSlidingExpiration,CacheItemPriority.High,null);
Get from the cache
DateTime expDeath = (DateTime)c.Get(userid.ToString())
I get null on the c.Get, even after I did have the key.
The code is in a different class than the page itself (the page uses it)
Thanks.
There are numerous ways you can store objects in ASP.NET
Page-level items -> Properties/Fields on the page which can live for the lifetime of the page lifecycle in the request.
ViewState -> Store items in serialised Base64 format which is persisted through requests using PostBack. Controls (including the page itself - it is a control) can preserve their previous state by loading it from ViewState. This gives the idea of ASP.NET pages as stateful.
HttpContext.Items -> A dictionary of items to store for the lifetime of the request.
Session -> Provides caching over multiple requests through session. The session cache mechanism actually supports multiple different modes.
InProc - Items are stored by the current process, which means should the process terminate/recycle, the session data is lost.
SqlServer - Items are serialised and stored in a SQL server database. Items must be serialisable.
StateServer - Items are serialised and stored in a separate process, the StateServer process. As with SqlServer, items must be serialisable.
Runtime - Items stored in the runtime cache will remain for the lifetime of the current application. Should the applciation get recycled/stop, the items will be lost.
What type of data are you trying to store, and how do you believe it must be persisted?
Right at the beginning of last year I wrote a blog post on a caching framework I had been writing, which allows me to do stuff like:
// Get the user.
public IUser GetUser(string username)
{
// Check the cache to find the appropriate user, if the user hasn't been loaded
// then call GetUserInternal to load the user and store in the cache for future requests.
return Cache<IUser>.Fetch(username, GetUserInternal);
}
// Get the actual implementation of the user.
private IUser GetUserInternal(string username)
{
return new User(username);
}
That was nearly a year ago, and it has been evolved a bit since then, you can read my blog post about it, let me know if thats of any use.
Your cache reference needs to be accessible to all items in your code - the same reference.
If you are newing up the Cache class every time, you are doing it wrong.
I have done almost the same things, but with a different code (and it work for me) :
(CacheKeys is an enum)
using System;
using System.Configuration;
using System.Web;
using System.IO;
public static void SetCacheValue<T>(CacheKeys key, T value)
{
RemoveCacheItem(key);
HttpRuntime.Cache.Insert(key.ToString(), value, null,
DateTime.UtcNow.AddYears(1),
System.Web.Caching.Cache.NoSlidingExpiration);
}
public static void SetCacheValue<T>(CacheKeys key, T value, DateTime expiration)
{
HttpRuntime.Cache.Insert(key.ToString(), value, null,
expiration,
System.Web.Caching.Cache.NoSlidingExpiration);
}
public static void SetCacheValue<T>(CacheKeys key, T value, TimeSpan slidingExpiration)
{
HttpRuntime.Cache.Insert(key.ToString(), value, null,
System.Web.Caching.Cache.NoAbsoluteExpiration,
slidingExpiration);
}
public static T GetCacheValue<T>(CacheKeys key)
{
try
{
T value = (T)HttpRuntime.Cache.Get(key.ToString());
if (value == null)
return default(T);
else
return value;
}
catch (NullReferenceException)
{
return default(T);
}
}

ASP.NET/Static class Race Condition?

I have an ASP.NET application with a lot of dynamic content. The content is the same for all users belonging to a particular client. To reduce the number of database hits required per request, I decided to cache client-level data. I created a static class ("ClientCache") to hold the data.
The most-often used method of the class is by far "GetClientData", which brings back a ClientData object containing all stored data for a particular client. ClientData is loaded lazily, though: if the requested client data is already cached, the caller gets the cached data; otherwise, the data is fetched, added to the cache and then returned to the caller.
Eventually I started getting intermittent crashes in the the GetClientData method on the line where the ClientData object is added to the cache. Here's the method body:
public static ClientData GetClientData(Guid fk_client)
{
if (_clients == null)
_clients = new Dictionary<Guid, ClientData>();
ClientData client;
if (_clients.ContainsKey(fk_client))
{
client = _clients[fk_client];
}
else
{
client = new ClientData(fk_client);
_clients.Add(fk_client, client);
}
return client;
}
The exception text is always something like "An object with the same key already exists."
Of course, I tried to write the code so that it just wasn't possible to add a client to the cache if it already existed.
At this point, I'm suspecting that I've got a race condition and the method is being executed twice concurrently, which could explain how the code would crash. What I'm confused about, though, is how the method could be executed twice concurrently at all. As far as I know, any ASP.NET application only ever fields one request at a time (that's why we can use HttpContext.Current).
So, is this bug likely a race condition that will require putting locks in critical sections? Or am I missing a more obvious bug?
If an ASP.NET application only handles one request at a time all ASP.NET sites would be in serious trouble. ASP.NET can process dozens at a time (typically 25 per CPU core).
You should use ASP.NET Cache instead of using your own dictionary to store your object. Operations on the cache are thread-safe.
Note you need to be sure that read operation on the object you store in the cache are threadsafe, unfortunately most .NET class simply state the instance members aren't thread-safe without trying to point any that may be.
Edit:
A comment to this answer states:-
Only atomic operations on the cache are thread safe. If you do something like check
if a key exists and then add it, that is NOT thread safe and can cause the item to
overwritten.
Its worth pointing out that if we feel we need to make such an operation atomic then the cache is probably not the right place for the resource.
I have quite a bit of code that does exactly as the comment describes. However the resource being stored will be the same in both places. Hence if an existing item on rare occasions gets overwritten the only the cost is that one thread unnecessarily generated a resource. The cost of this rare event is much less than the cost of trying to make the operation atomic every time an attempt to access it is made.
This is very easy to fix:
private _clientsLock = new Object();
public static ClientData GetClientData(Guid fk_client)
{
if (_clients == null)
lock (_clientsLock)
// Check again because another thread could have created a new
// dictionary in-between the lock and this check
if (_clients == null)
_clients = new Dictionary<Guid, ClientData>();
if (_clients.ContainsKey(fk_client))
// Don't need a lock here UNLESS there are also deletes. If there are
// deletes, then a lock like the one below (in the else) is necessary
return _clients[fk_client];
else
{
ClientData client = new ClientData(fk_client);
lock (_clientsLock)
// Again, check again because another thread could have added this
// this ClientData between the last ContainsKey check and this add
if (!clients.ContainsKey(fk_client))
_clients.Add(fk_client, client);
return client;
}
}
Keep in mind that whenever you mess with static classes, you have the potential for thread synchronization problems. If there's a static class-level list of some kind (in this case, _clients, the Dictionary object), there's DEFINITELY going to be thread synchronization issues to deal with.
Your code really does assume only one thread is in the function at a time.
This just simply won't be true in ASP.NET
If you insist on doing it this way, use a static semaphore to lock the area around this class.
you need thread safe & minimize lock.
see Double-checked locking (http://en.wikipedia.org/wiki/Double-checked_locking)
write simply with TryGetValue.
public static object lockClientsSingleton = new object();
public static ClientData GetClientData(Guid fk_client)
{
if (_clients == null) {
lock( lockClientsSingleton ) {
if( _clients==null ) {
_clients = new Dictionary``();
}
}
}
ClientData client;
if( !_clients.TryGetValue( fk_client, out client ) )
{
lock(_clients)
{
if( !_clients.TryGetValue( fk_client, out client ) )
{
client = new ClientData(fk_client)
_clients.Add( fk_client, client );
}
}
}
return client;
}

Resources