ZF2 Mysql rollback commit function - mysql

I was wondering if there is a function such as mysql rollback commit available in
Zend Framework 2?
I need to insert multiply rows in the same tabel coming from one form submit.
Nick

In ZF2, the beginTransaction(), commit() and rollback() methods are in the ConnectionInterface.
As far as I can see, you probably have to write code something like this:
$dbAdapter->getDriver()->getConnection()->beginTransaction();
. . .
$dbAdapter->getDriver()->getConnection()->commit();
See:
http://framework.zend.com/apidoc/2.1/classes/Zend.Db.Adapter.Driver.ConnectionInterface.html

This cannot be used to update two tables in the same transaction.

Related

Calling MySQL stored procedure in ROR 4

There are few example out there but non of them are very clarified (or on old version).
I want to call MySQL procedure and check the return status (in rails 4.2). The most common method I saw is to call result = ActiveRecord::Base.connection.execute("call example_proc()"), but in some places people wrote there is prepared method result = ActiveRecord::Base.connection.execute_procedure("Stored Procedure Name", arg1, arg2) (however it didn't compiled).
So what is the correct way to call and get the status for MySQL procedure?
Edit:
And how to send parameters safly, where the first parameter is integer, second string and third boolean?
Rails 4 ActiveRecord::Base doesn't support execute_procedure method, though result = ActiveRecord::Base.connection still works. ie
result = ActiveRecord::Base.connection.execute("call example_proc('#{arg1}','#{arg2}')")
You can try Vishnu approach below
or
You can also try
ActiveRecord::Base.connections.exec_query("call example_proc('#{arg1}','#{arg2}')")
here is the document
In general, you should be able to call stored procedures in a regular where or select method for a given model:
YourModel.where("YOUR_PROC(?, ?)", var1, var2)
As for your comment "Bottom line I want the most correct approach with procedure validation afterwards (for warnings and errors)", I guess it always depends on what you actually want to implement and how readable you want your code to be.
For example, if you want to return rows of YourModel attributes, then it probably would be better if you use the above statement with where method. On the other hand, if you write some sql adapter then you might want to go down to the ActiveRecord::Base.connection.execute level.
BTW, there is something about stored proc performance that should be mentioned here. In several databases, database does stored proc optimization on the first run of the stored proc. However, the parameters that you pass to that first run might not be those that will be running on it more frequently later on. As a result, your stored-proc might be auto-optimized in a "none-optimal" way for your case. It may or may not happen this way, but it is something that you should consider while using stored procs with dynamic params.
I believe you have tried many other solutions and got some or other errors mostly "out of sync" or "closed connection" errors. These errors occur every SECOND time you try to execute the queries. We need to workaround like the connection is new every time to overcome this. Here is my solution that didn't throw any errors.
#checkout a connection for Model
conn = ModelName.connection_pool.checkout
#use the new connection to execute the query
#records = conn.execute("call proc_name('params')")
#checkout the connection
ModelName.connection_pool.checkin(conn)
The other approaches failed for me, possibly because ActiveRecord connections are automatically handled to checkout and checking for each thread. When our method tries to checkout a connection just to execute the SP, it might conflict since there will be an active connection just when the method started.
So the idea is to manually #checkout a connection for the model instead of for thread/function from the pool and #checkin once the work is done. This worked great for me.

Log table using JPA 2.1, EclipseLink, JSF 2.0

I already made triggers to log the actions before persisting, updating and deleting the mapped entities, but it's only within MySQL, so I think I must do an "application-level trigger" using annotations #PostPersist, #PostUpdate and #PostDelete.
So, when entity e.g. Category gets persisted, a method for inserting info into a log table is thrown, with the following SQL:
INSERT INTO log (date_hour, table, id_tuple, user)
VALUES (NOW(), 'category', " + id + ", '" +
FacesContext.getCurrentInstance().getExternalContext().getRemoteUser() + "')";
I made exactly like that, using createNativeQuery then query.executeUpdate() but nothing happened.
What's the best approach for doing what I want? Reminding that I'm using EclipseLink.
You can log all changes to an entity type with little effort using EclipseLink's History policy: http://wiki.eclipse.org/EclipseLink/Examples/JPA/History
Assuming you are CDI you can create an interceptor like described in: Oracle Tutorial CDI Interceptor
In this interceptor you can create your insert in the log table.
But keep in mind that logging usually slows an application down much. Consider using loglevels that you normally just log errors instead of everything

Perform select and multiple inserts as transaction using C Connector?

I am using MySQL. I have a select statement followed by a number of insert statement done using the C Connector. I would like to know how to put them all under one transaction and finally commit then.
I have gone through the MySQL 5.0 Reference Manual and C API Function Overview it have this function mysql_commit()? I must have a start transaction (how to set this is it by just turning off the autocommit()) and finally only commit right?
As far as I understand, there is no mysql_starttransaction() or something similar; so you're stuck with something like:
mysql_autocommit(conn, 0);
//Do stuff here
mysql_commit(conn); //...or mysql_rollback(conn);
I would rather use the "query" method for all these calls:
mysql_query(conn, "START TRANSACTION");
//Do stuff here
mysql_query(conn, "COMMIT"); //...or mysql_query(conn, "ROLLBACK");
Also see this documentation.

Codeignighter Record wont insert

Using CI for the first time and i'm smashing my head with this seemingly simple issue. My query wont insert the record.
In an attempt to debug a possible problem, the insert code has been simplified but i'm still getting no joy.
Essentially, i'm using;
$data = array('post_post' => $this->input->post('ask_question'));
$this->db->insert('posts', $data);
I'm getting no errors (although that possibly due to disabling them in config/database.php due to another CI related trauma :-$ )
Ive used
echo print $this->db->last_query();
to get the generated query, shown as below:
INSERT INTO `posts` (`post_post`) VALUES ('some text')
I have pasted this query into phpMyAdmin, it inserts no problem. Ive even tried using $this->db->query() to run the outputted query above 'manually' but again, the record will not insert.
The scheme of the DB table 'posts' is simply two columns, post_id & post_post.
Please, any pointers on whats going on here would be greatly appreciated...thanks
OK..Solved, after much a messing with CI.
Got it to work by setting persistant connection to false.
$db['default']['pconnect'] = FALSE;
sigh
Things generally look ok, everything you have said suggests that it should work. My first instinct would be to check that what you're inserting is compatible with your SQL field.
Just a cool CI feature; I'd suggest you take a look at the CI Database Transaction class. Transactions allow you to wrap your query/queries inside a transaction, which can be rolled back on failure, and can also make error handling easier:
$this->db->trans_start();
$this->db->query('INSERT INTO posts ...etc ');
$this->db->trans_complete();
if ($this->db->trans_status() === FALSE)
{
// generate an error... or use the log_message() function to log your error
}
Alternatively, one thing you can do is put your Insert SQL statement into $this->db->query(your_query_here), instead of calling insert. There is a CI Query feature called Query Binding which will also auto-escape your passed data array.
Let me know how it goes, and hope this helps!

How to change update statement before executing: Linq2Sql Classes

I have implemented Change Tracking (http://msdn.microsoft.com/en-us/library/cc280462.aspx) on some tables I am using Linq2Sql on.
As a part of this I need to add the below SQL to the start of the update statements generated.
DECLARE #originator_id varbinary(128);
SET #originator_id = CAST('SyncService' AS varbinary(128));
WITH CHANGE_TRACKING_CONTEXT (#originator_id)
....generated statements....
....
....
I know I can create stored procedures and manually map the fiels but I would like to avoid this if possible.
does anyone know a way to override and edit the SQL on SubmitChanges()?
You can override the Update method by implementing partial classes on your datacontext that LINQ to SQL will call instead. Just give it the signature:
partial void UpdateClassName(ClassName instance)
You can also pass through to what it would normally do using:
ExecuteDynamicInsert(instance);
Unfortunately there is no mechanism just to get the intended SQL back for inserts/update/deletes (you can get SELECT statements with GetCommand on the DataContext)