I'm trying Laravel transaction for the first time... I do most of my queries with Eloquent and since there no transaction there I have to do a mixture of Eloquent and query builder.
Here is my code:
DB::beginTransaction();
try{
Setting::truncate();
Setting::insert($data);
DB::commit();
jok('all ok');
}
catch (\Exception $e)
{
DB::rollback();
jerror('some error accorded! ');
}
So I've tied to add some invalid data to Settings and i got the some error accorded error as expected but the query before INSERT Setting::truncate(); was executed anyway and I ended up with a empty table.
So either I'm doing something wrong or transaction doesn't work on truncate.
TRUNCATE TABLE in a database transaction will cause a implicit COMMIT action. DELETE does not have that same behavior, so you can safely run
DELETE FROM tblname
This will clear your table and still keep the desired rollback feature of a transaction.
See the MySQL documentation on TRUNCATE. The bullet points explain this functionality http://dev.mysql.com/doc/refman/5.7/en/truncate-table.html
A better solution to do delete is to use Model method:
Setting::query()->delete();
Related
How do I use the Commit statement correctly? Do I have to use commit statement for every insert statement and every function? For example, if I alter a table to add a column do I have to use a commit statement?
If you run a DDL statement (CREATE, ALTER, DROP, GRANT, etc) then:
Oracle Database implicitly commits the current transaction before and after every DDL statement.
If you run a DML statement (INSERT, UPDATE, DELETE, SELECT, CALL, MERGE) then:
These statements do not implicitly commit the current transaction.
and you will need to manually commit the uncommitted transactions (but you do not have to COMMIT after every statement).
If you want to perform a partial rollback then you can use SAVEPOINTs.
You should not put COMMIT statements in functions or procedures so that you can use multiple functions/procedures in a single transaction and then COMMIT or ROLLBACK that entire transaction.
Commits are needed when you change data in your tables (insert, update and delete). As long as you do not commit, other users will not see the changed data and you still have the option to undo the changes by executing a rollback.
There is no need to commit after every single statement.
Commits are not needed when changing the table itself (alter table). In fact, the alter table statement issues an implicit commit.
Some more on implicit/explicit commit statements in Oracle
Based on accumulated experience and "good practices" - you should not implement "commit" statements in your functions/procedures (most of the time, depends on the task, what are you try to achieve). The "commit" decision should lie on the user, who invokes your function/procedures.
What you can implement, is a "rollback", when exceptions are occurred/caught.
Often, when stored procedures or function are invoked from the application/web part, they are auto-committed (the option can be changed within transaction methods, as far i know, at least in java).
try like that:
try {
// First of all, let's begin a transaction
$db->beginTransaction();
// A set of queries; if one fails, an exception should be thrown
$db->query('first query');
$db->query('second query');
$db->query('third query');
// If we arrive here, it means that no exception was thrown
// i.e. no query has failed, and we can commit the transaction
$db->commit();
} catch (Exception $e) {
// An exception has been thrown
// We must rollback the transaction
$db->rollback();
}
New code I'm trying to code a trigger that doesn't allow duplicate values to ensure a band isn't playing at the same time. I get the below compilation error and can't figure it out:
Pretty new to oracle, so any help would be appreciated.
First of all, you do not need a trigger to prevent duplicate records to be inserted. Create a unique index on band_playing and play_time fields and this will take care of any duplicate records.
Regarding the error message: an insert statement creates a new record, therefore there is no :old version of the record, only a :new one. You would need to execute a select to check if a row with the same values exist in the table. Also, as #Littlefoot noted in his comment, an if must be closed by an end if; statement, which is missing from your code.
I am using JdbcDaoSupport in DAO class for database coding in my project and there is a scenario for "deleting a member" from a table. I am using getJdbcTemplate.update("delete MEMBERINFO where memid= "+id); method. But if there is no data in the table, it doesn't raise any exception. The criteria is such that if there are no records in the table and yet user is trying to delete a record, then user will receive an error message saying "No data found". But for that, i need to raise an exception.
I am using oracle 11g XE.
Also same problem for getJdbcTemplate.query("select * from MEMBERINFO");
If there is no data it does not raise any exception.
Actually JdbcTemplate's update method returns int - number of rows was affected. All you need is to check amount of rows returned. If it's 0 the you can show an error message.
As for query it's fine that list is empty. If you need just one object use
queryForObject() method. It throws exception if no result is found.
BTW: The getJdbcTemplate.update("delete MEMBERINFO where memid= "+id); contains SQL injection. Use parameters instead.
I have and application which uses Adodb to insert data in Oracle table(customers database).
Data is successfully inserted if there are no errors.
If there is any error like invalid datatype etc. Error is raised and captured by my application and dumped in log gile.
My customer has written their own triggers on this particular table. When a record is inserted few other checking are done be fore the data insertion
Now all fine until now.
But recently we found that many a times data is not inserted in the oracle table.
When checked in log file no error was found.
Then I logged the query which was executed.
Copied the query to oracle Sql prompt and executed it gave error of trigger.
My Issue is
Customer is not ready to share the details of trigger.
Error is not raised while inserting to oracle table so we are not able to log it or take any action.
The same qry when executed directly in oracle the trigger errors are show.
Help needed for
Why the error is not raised in ADODB
Do I have to inform customer to implement any error raising
Anything that you can suggest for resolving the issue
I have 0% to 10% knowledge of Oracle
"Copied the query to oracle Sql prompt and executed it gave error of trigger." Since the ADO session doesn't report an error, it may be that the error from the trigger is misleading. It may simply be a check on the lines of "Hey, you are not allowed to insert into this table except though the application".
"Error is not raised while inserting to oracle table so we are not able to log it or take any action."
If the error isn't raised at the time of insert, it MAY be raised at the time of committing. Deferred constraints and materialized views could give this.
Hypothetically, I could reproduce your experience as follows:
1. Create a table tab_a with a deferrable constraint initially deferred (eg val_a > 10)
2. The ADO session inserts a row violating the constraint but it dooesn't error because the constraint is deferred
3. The commit happens and the constraint violation exception fires and the transaction is rolled back instead of being committed.
So see if you are catering for the possibility of an error in the commit.
It may also be something else later in the transaction which results in a rollback of the whole transaction (eg a deadlock). Session tracing would be good. Failing that, look into a SERVERERROR trigger on the user to log the error (eg in a file, so it won't be rolled back)
http://download-west.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_7004.htm#i2153530
You can log your business logic in log table.
But you have to use stored procedure to log the message.
Stored procedure should have pragma Transaction such that your log data must be saved in log table.
You are trigger should have error handling - and in error handling , you have to call Logged stored procedure (which have pragma transaction)
I've never used adodb ( and I assume that is what you are using, not ADO.NET?).. But, a quick look at its references leads to this question.. Are you actually checking the return state of your query?
$ok = $DB->Execute("update atable set aval = 0");
if (!$ok) mylogerr($DB->ErrorMsg());
I tried to put it in a sentence but it is better to give an example:
SELECT * FROM someTable WHERE id = someID;
returns no rows
...
some time passes (no inserts are done to the table and no ID updates)
...
SELECT * FROM someTable WHERE id = someID;
returns one row!
Is it possible that some DB mechanism prevents first SELECT to return row?
Oracle log has no errors.
No transactions are rolled back when two selects are executed.
You can't see uncommitted data in another session. When did the commit happen?
EDIT1: Are you the only one using this database? Or did/do you have multiple sessions?
I think in another session you or someone else has inserted this row, you do your select and you don't see this row. After that a commit happens in the other session (maybe implicit because a session is closed) and then you see this row when you select again.
I can think of other explanations, but I first want to know are you only one using this database.
With read consistency as provided by Oracle, you should not see a row appear like that. If you are running in some mode with automatic commits, so that each statement is a self-contained transaction, then read consistency is not being violated. Which program are you using to access the database? I agree with the other observations; the row should not appear if your session is not inserting it and no other session is active at the same time. I don't know of a DBMS that indulges in spontaneous data generation.
Don't you have scheduled jobs in that Oracle?