Grails - how to connect to another database during an action - grails

What I need to do is this (either in an action or a service):
someAction() {
// connect to database
def otherDatasource = new Datasource(otherOptions)
if (otherDatasource.isOnline()) {
def list = ExclusiveDomainFromOtherDatasource.list()
// do stuff with the data...
otherDatasource.close()
}
}
I'm not using datasources plugin because the other database may be offline and the app connects during first-run, or maybe I'm forgetting something.
I know I could use some basic jdbc library and make a raw sql for getting the data, but that isn't very groovish, is this the only way? or is there a plugin that allow me to do that?

Unless you're using some sort of custom DataSource, there is no isOnline() method, so you might as well just use the DataSources plugin.
Actually, newer versions of grails have multiple-datasource support built-in, so you don't need the plugin.
I think that you're just going to have to try to get a connection from the DataSource, and be prepared to catch and handle the exception that you'll get if the database is offline.
A well-configured database conneciton pool should allow you to start connecting successfully once the database comes online.

Related

How to fix connection close issue in synchronised method?

In our application, we are using grails framework and SQL server for database. We have multiple sites and those sites can have multiple users (a few users) and if they are accessing the same method via AJAX that can cause issue so we made the that method as synchronized method and to minimize the database interaction we are storing data in map on site basis since all the user from one site will get the same data, and if the data is older than 10 seconds we get the data from database and update the map object. Here we are getting a lot of database connection close issues on the very first line of synchronized method where we are getting site object from database. What is the issue here and how we can resolve the issue?
def synchronized getData(params){
Site site = Site.get(params.siteId)
// Here we are checking whether site data does not exists in map
// or the data expired (10 second older data) then we get data from
// database and update the map object
// Then here we create new list object from the data in map object
return list
}
Difficult to figure out the exact problem without more information here. Several things stand out...
I'm not especially familiar with using the synchronized keyword in front of a service method, I would recommend trying the synchronized annotation with a static object key:
private static final myLock = new Object()
#Synchronized("myLock")
void getData() {
//do stuff
}
or synchronizing explicitly within the method
void getData() {
synchronized(myLock) {
//do stuff
}
}
I don't know if that's related to your connection closing issues, but worth a try.
But also notably, grails and hibernate provide caching of database retrieves, so if you're loading the same data that's been loaded into hibernate cache, you don't need to cache this in a Map locally... grails is already doing that for you. Site site = Site.get(params.siteId) will NOT make a database call if it's been called recently and is already cached by the framework.
I would strongly suggest running some performance checks just making that call vs. caching in a Map object, especially if you're expiring in ~10s anyway.

Grails do not commit after a successful service call

I'm performing the following logic on a single Service in grails 2.4.4.
class SampleService {
void process(params1, params2) {
SampleDomain1 sd1 = new SampleDomain1()
sd1.setProperties(params1)
sd1.save()
SampleDomain2 sd2 = new SampleDomain2()
sd2.setProperties(params2)
sd2.save()
}
}
What I understand is that Services are by default transactional. If sd1.save() is successful but sd2.save() is not, it will rollback the changes and will throw an error. While if both are successful, both are committed upon service's exit.
If my understanding is correct, then both of it should already been persisted to the database. However, the problem is: it does not— unless if you explicitly use the flush: true parameter based on my tests using the same set of params1 and params2.
sd1.save(flush: true)
SampleDomain2 sd2 = new SampleDomain2()
sd2.setProperties(params2)
sd2.save(flush: true)
}
Which, by the way is what I am really avoiding (what would be the point setting it as #Transactional). If that's the catch of Hibernate 4 / Grails 2.4, what do I need to do to make my services to commit at every end of a service call again? Do I need to configure any global configuration of Grails? I really need to flush my Domain classes at the end of every service automatically.
Note
I've already assured that the data is correct, including calling .validate() and other checker. Success in performing .save(flush: true) proves that. The problem I found is regarding to the update on Grails 2.4 on its FlushMode. Now, maybe what I really need is a global settings to override this.
If your data is not being flushed to the database layer there are some possibilities that come to mind.
There's some kind of error when trying to save to the database, you can try passing failOnError=true parameter to the .save() calls to see it clearly. (Actually setting this globally is a good idea since silently failing db calls are a migraine)
You are calling this service method from within the same service object. This will not allow the underlying spring declarative transactions to work due to the use of proxies.
You might have annotated some other method in the same service, in which case the default transactional support is no longer available for the remaining un-annotated (is this even a word?) methods.
You might have created the Service somewhere outside of service folder, not quite sure if this can cause an issue since I've never tried it out.
You have failed to sacrifice a goat to the Groovy and Grails Gods and they are messing with your head.
Edit :
I'm going to try to answer the points in your new edit.
Have you tried failOnError? It might be a issue that occurs when both objects are flushed to the DB at once, instead of manually committing them one at a time.
By figuring out a way to auto flush on save, you are going to be bypassing the transactions altogether AFAIK, now if I'm wrong then by all means go for it. But do test it out first before assuming.
Somewhere on my DataSource.groovy configuration, there is this line:
hibernate {
...
singleSession = true // configure OSIV singleSession mode
flush.mode = 'manual' // OSIV session flush mode outside of transactional context
^^^^^^^^^^
}
Which explicit states that every save should be flushed manually. As a solution, I comment out this line. After that, every database transaction now commits every time it exists a Service.

Copy from one datasource to another in grails 2

I'm trying to use a domain that's configured for two datasources to copy data from one datasource to another. The documentation implies that this is straight-forward but I can only get it to save to the default datasource.
class LocalTransaction {
static mapping = {
datasources(['DEFAULT','migration'])
}
}
First I tried finding the transaction from the default datasource via LocalTransaction.findAllBy..(), then attempt to save changes via tr.migration.save(flush:true,failOnError:true) but the changes are saved to DEFAULT.
I think tried to create a new instance via LocalTransaction.migration.get(lt.id), copy the data over and then save, but that isn't saving to the migration datasource either.
Thanks,
Bill
Grails 2.0 has added support for multiple datasources to its core (this was formerly provided by a plugin). Please read the following section in the Grails documentation http://grails.org/doc/2.0.0.RC1/guide/conf.html#multipleDatasources
To save data in a specific datasource, you have to use its name before calling the save() closure, for example:
localTransactionObj.migration.save()
Hope that helps!

Why does all data go away when restarting Neo4j?

I don't understand this paradigm I guess?
For a small single server or development environment... I hate having to load 100's of thousands of records just to analyze it in a graph... am I missing the big picture here?
UPDATE (3/21/2012 10:38a):
My current setup:
Default Install
Default Configs
Server Setup
Creating nodes via REST API
How do you instantiate your database, embedded or server? Are you running ImpermanentGraphDatabase, because that's the in-memory test database. If you use the normal EmbeddedGraphDatabase your graph is persisted trasactionally along the way when you insert your data.
Please give a little more information.
If using Java embedded transactions must be closed when saving objects or they might get lost. In earlier versions this was done by calling finally { tx.finish(); }, later versions (2.1+) it should happen automatically when instantiated within the try-with-resource. (This makes it possible to run into problems if the Transaction tx is instantiated outside the try clause).
GraphDatabaseService graphDb = new GraphDatabaseFactory().newEmbeddedDatabase(DB_PATH);
try (Transaction tx = graphDb.beginTx()) {
// create some nodes here
}

Connection Status of SQLite in IOS

Is there a way one can check the connection status of a SQLite DB in IOS. I do not want to keep opening the db connection again and again. As a work around, I have put the SQLite DB object into a static variable and check if the object is NIL, else use the object as is.
Is there a simpler and cleaner way to do this
A lot of SQLite Wrappers for iOS provide this functionality. Here is a library I wrote for handling SQLite connections which you can use to check the status of a connection: https://github.com/ziminji/objective-c-sql-query-builder
First of all, I would recommend using FMDB instead of SQLite directly.
To answer your question: don't bother. I have many apps, with many users and I have never seen the database "connection" fail. It just doesn't fail, it's not a network connection, just an open file.
Try www.github.com/pmurphyjam/DBExample It's an Xcode project that uses SQLite. It abstracts the entire SQL layer for you so you can concentrate on just writing SQL queries. It does large transactions also. The SQL syntax is exactly like FMDB, and it also uses Dictionaries for complex queries. Here's an example:
For selects NSMutableArray = GetRecordsForQuery:#"select firstName, lastName from Company where lastName = ? ",#"Smith",nil];
OR For inserts, deletes or updates
BOOL = ExecuteStatement:#"insert into Company (firstName, lastName) values(?,?)",#"John",#"Smith", nil];
There is an example project for using SQLite here you can refer to: https://github.com/AaronBratcher/ABSQLite
It has classes for accessing SQLite in a more traditional database way.

Resources