How it is possiblle to flush to disk a transaction programmatically using Xodus? - xodus

I m trying to flush to disk a transaction without to set in the configuration durable write.
It is possible to command to flush just for a specific transaction?

Speaking of the Environments API, it is not possible to configure particular transaction to be durable.
There is a work around: you can manually invoke the EnvironmentImpl#flushAndSync() method after a transaction is flushed or committed. The method flushes not flushed data and forces OS to sync modified files and directory structure to storage device. Though, there can be a race when another transaction can be executed in parallel after your transaction, which you'd like to be durable, is flushed/committed and before the EnvironmentImpl#flushAndSync() method is invoked. To solve the race, you can use commit hook. For given Transaction txn and EnvironmentImpl env, define the following commit hook:
txn.setCommitHook(new Runnable() {
#Override
public void run() {
env.flushAndSync();
}
});
Probably, it makes sense to expose the EnvironmentImpl#flushAndSync() method to the API.

Related

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.

Netezza stored procedure run

I have 12 stored procedures in netezza. I call these procedures using nzsql command from a shell script. I want to run these procedure in parallel to increase throughput. How can I do this?
Serializable
If the stored procedures do not affect the same tables, then you can just fork the calls from bash:
nzsql -Atc "call sp1();" &
nzsql -Atc "call sp2();" &
nzsql -Atc "call sp3();" &
...
wait
See other answers about forking.
Not Serializable
If the stored procedures affect the same tables, you'll need to set serializability off in the connection or transaction that is affected. I haven't done this in a stored procedure (and you may not be able to), but this should work:
nzsql -Atc "set serializable = false; call sp1();" &
nzsql -Atc "set serializable = false; call sp2();" &
nzsql -Atc "set serializable = false; call sp3();" &
...
wait
See the docs for more information on the serializable isolation level. You'll be responsible for making sure that the data the stored procedures are modifying do not collide in some fashion, as you'll get dirty reads.
To elaborate on #Jeremy Fortune's answer, There are three scenarios in which the system aborts a transaction to preserve serializability:
An update or delete statement is running concurrently with another
update or delete statement on the same table.
Two concurrent transactions that each perform a SELECT FROM and an
INSERT INTO the same table. This could occur as a self-inserting statement or multiple statements in any order. Note that up to 31 concurrent inserts into the same table are supported, provided that no more than one of these also selects from the same table.
Two concurrent transactions, the first of which selects from table1
and updates, inserts or deletes from table2 while the second transaction selects from table2 and updates, inserts or deletes from
table1.
You can read more about it here.
However serialized transaction can be in a queue before failing and system automatically retries until it all time outs after X minutes, X is defined by serialization_queue_timeout system variable.
However this only applies to implicit transactions (transactions without BEGIN and COMMIT block), and most of store procedure transactions are explicit transactions (it's also advantage of using store procedure, everything gets rolled back if something fails, unless you have used AUTOCOMMIT ON option placed somewhere inside the store procedure), which won't let you take advantage of the serialization queue.

Correct way to use DbConnection, DbTransaction with connection pooling, transactionScope and dependency injection?

I have a Oracle database and I'm using the Oracle.ManagedDataAccess.
In some cases I will need to do actions in a single transactions, but often not.
I'm not sure what the best way to handle DbConnection objects within a single TransactionScope.
I could inject a DbConnection into the repositories and then even use LifetimePerScope to ensure they all get the same DbConnection instance. But is that a smart move, is it ok to .Open() the connection once.
using (var scope = _lifetimeScope.BeginLifetimeScope())
{
var connection = scope.Resolve<IDbConnection>();
var personRepo = scope.Resolve<IPersonRepository>();
var workRepo = scope.Resolve<IWorkRepository>();
connection.Open();
var transaction = connection.BeginTransaction()
personRepo.DeleteById(someId);
workRepo.DeleteByPersonId(someId);
transaction.Commit();
}
This would force me to always use a LifetimeScope, even if not using a Transaction, and open the connection outside the repository method.
Are TransactionScopes dependent on a single connection or can I open multiple connections (how does the connectionPool handle that while a transaction is open?) within the same transaction?
I'm a total outsider to DbConnections and all that so I might be totally misunderstanding the best way to use TransactionScope and DbConnections.
Possible duplicate of: Why always close Database connection?
Since this has a bounty, I can't flag it as a duplicate :(
Anyway, connection pooling is largely done for you. You should close connections as soon as you can, to return them to the pool.
Transactions are related to a specific open connection and should be finished when closing the connection.
TransactionScope related to BeginTransaction() is specific to a connection.
If you want to maintain a transaction across multiple connections(multiple DBs,resources), then you need DTC aware TransactionScope. Here is a similar SO post. You need to use Oracle.ManagedDataAccessDTC.dll to facilitate that.
You might want to go through these links:
1.All about transactionscope
2.How To Configure DTC to Support Oracle Transactions
Hope this helps.

why read-only access is writing to my db, in GORM?

In my app, I have a code like this:
// 1
Foo.get(123).example = "my example" // as expected, don't change value in db
// 2
Foo.get(123).bars.each { bar ->
bar.value *= -1 // it's changing "value" field in database!! WHY?
}
note: Foo and Bar are tables in my DB
Why is gorm saving in database is second case?
I don't have any save() method in code.
Tks
SOLVED:
I need to use read() to get a readonly session.
(Foo.discard() also works)
Doc: http://grails.org/doc/latest/guide/5.%20Object%20Relational%20Mapping%20%28GORM%29.html#5.1.1%20Basic%20CRUD
(In the first case, I guess I made mistest)
Both should save, so the first example appears to be a bug. Grails requests run in the context of an OpenSessionInView interceptor. This opens a Hibernate session at the beginning of each request and binds it to the thread, and flushes and closes it at the end of the request. This helps a lot with lazy loading, but can have unexpected consequences like you're seeing.
Although you're not explicitly saving, the logic in the Hibernate flush involves finding all attached instances that have been modified and pushing the updates to the database. This is a performance optimization since if each change had been pushed it would slow things down. So everything that can wait until a flush is queued up.
So the only time you need to explicitly save is for new instances, and when you want to check validation errors.

Changes not reflected in Database while using entity framework

I am accessing my database through ADO.NET Entity framework in MVC 3 Application.
I am updating my database through Stored Procedure.
But the changes are not reflected at run time.I mean to say i am able to see the changes only after restarting it.
What is the reason for the problem and How can i avoid it ?
I am using Repository pattern So at repository My code look like this
Ther Is One Function Which Save Changes
public void SaveNewAnswer(AnswerViewModel answer,string user)
{
SurveyAdminDBEntities _entities = new SurveyAdminDBEntities();
_entities.usp_SaveNewAnswer(answer.QuestionId, answer.AnswerName, answer.AnswerText, answer.AnswerOrder, answer.Status, user);
_entities.SaveChanges();
}
Data Retreival Code
public IEnumerableGetMultipleChoiceQuestions(string questionId)
{
SurveyAdminDBEntities _entities = new SurveyAdminDBEntities();
_entities.AcceptAllChanges();
_entities.SaveChanges();
return _entities.usp_GetMultipleChoiceQuestions(Int32.Parse(questionId));
}
But Changes are not reflected till the time i don't clode the session of the browser and run it again .
Please help !
Thank You In advance
Are you calling context.SaveChanges() on your Entities (DbContext/ObjectContext) object? Are you using a transaction that you haven't committed?
If you have an uncommitted transaction in your sproc, you can try creating your own entity transaction and seeing if committing your transaction will commit the nested transaction as well. The problem is that calling SaveChanges() automatically begins and commits a transaction, so this may not be any different than that.
I would also call _entities.AcceptAllChanges() in your save operation.
public void SaveNewAnswer(AnswerViewModel answer,string user)
{
SurveyAdminDBEntities _entities = new SurveyAdminDBEntities();
_entities.Connection.Open();
System.Data.Common.DbTransaction tran = _entities.Connection.BeginTransaction();
try
{
_entities.usp_SaveNewAnswer(answer.QuestionId, answer.AnswerName, answer.AnswerText, answer.AnswerOrder, answer.Status, user);
_entities.SaveChanges(); // automatically uses the open transaction instead of a new one
tran.Commit();
}
catch
{
tran.Rollback();
}
finally
{
if (_entities.Connection.State == System.Data.ConnectionState.Open)
_entities.Connection.Close();
_entities.AcceptAllChanges();
}
}
Is your stored procedure doing an explicit commit? Things run in a database session will be available for that session, but not available to any other session until the action is committed.
When you pull data out of your database into your context that data is kept in memory, separate from the actual database itself.
You will see the changes if you create a new context object instance and load the data from the database with it.
It's good practice to not use the same instance of your context object but create them on an as needed basis for individual transactions with the database. In your case if you're updating via function imports instead of the context.SaveChanges() method then you need to refresh your context with the updated data after you commit those changes.
Add this to your connect string (assuming sql 2005)
transaction binding=Explicit Unbind;
if the data is no longer available after session reset, then the problem is indeed with a transaction, if the data is then available after reset, then your problem is something different and we'll likely need more details.

Resources