commit after select - sql

I have read the explanations when a commit may be neccessary after a select statement for DB2 and MySQL:
Is a commit needed on a select query in DB2?
Should I commit after a single select
My question is when and why would it be important to commit after executing a select statement using Oracle?

If you did a SELECT ... FOR UPDATE; you would need a COMMIT or ROLLBACK to release the records held for update. Otherwise, I can't think of any reason to do this.

there are only a few situations that I can think of that you may want to commit after a select.
if your select is joining on database links, a transaction will be created. if you attempt to close this link, you'd get an error unless you committed/rolled back the transaction.
select for update (as DCookie says) to release the locks.
to remove an serialized isolation level if set or to add one, if you've been selecting from db links prior to invoking this.

Related

SELECT after INSERT doesn't select recently added rows

This is quite a basic and somewhat strange question, I guess. Suppose I have a stored procedure that contains an INSERT (or MERGE) statement, followed by a SELECT statement.
Can I always assume that the INSERT statement has finished writing/committing data when I run SELECT? Is it to be expected that the SELECT statement (sometimes) doesn't select all recently inserted rows? If so, what options do I have to make the SELECT statement wait for the INSERT statement to have finished (in a stored procedure) or include possibly uncommitted data?
If it is in the same session it will see it , whether committed or not, unless it has been rolled back.
Once committed other sessions can see it.
If 'select' is from different session and you want read uncommited data
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

How does statement, 'for update' works?

I am sorry in advance if I sound noob. I am looking through code for stored procedure and I came across:
select
...
into
....
from
....
where
....
for update;
I don't understand what is the purpose of for update;.
I do understand normal update, similar to: http://www.mkyong.com/oracle/oracle-stored-procedure-update-example/. But not able to get my head around for update; and its purpose.
I looked around but could not find clear explanation.
From the document:
The SELECT FOR UPDATE statement allows you to lock the records in the
cursor result set. You are not required to make changes to the records
in order to use this statement. The record locks are released when the
next commit or rollback statement is issued.
Also refer the Oracle docs which says:
The FOR UPDATE clause lets you lock the selected rows so that other
users cannot lock or update the rows until you end your transaction.
You can specify this clause only in a top-level SELECT statement, not
in subqueries.
So the purpose is quite clear it is used when you want to lock your rows during a transaction so that it cannot be used by some other transaction.
You can also refer: FOR UPDATE Clause in a SELECT Statement to get an idea as to how we can use it.

What does COMMIT do?

please I want to understand the difference between the folowing two statements:
insert into table_name values (,,,,,);
and
insert into table_name values (,,,,,);
commit;
If you insert data without commit you can select data from database and see it. But other users can't.
It's better to look to sql documentation:
Until you commit a transaction:
You can see any changes you have made during the transaction by
querying the modified tables, but other users cannot see the changes.
After you commit the transaction, the changes are visible to other
users' statements that execute after the commit.
You can roll back (undo) any changes made during the transaction with
the ROLLBACK statement (see ROLLBACK.
for example here Oracle Documentation
and some info about transactions
All the DML (insert, update , delete) to be inserted in the database you have to commit them, like approve that you want to add them in the database. If you dont commit DML statment , it will not be enter in the database.
what is commit ?
Docs.oracle cant describe it better
Use the COMMIT statement to end your current transaction and make
permanent all changes performed in the transaction. A transaction is a
sequence of SQL statements that Oracle Database treats as a single
unit. his statement also erases all savepoints in the transaction and
releases transaction locks.

Commit statement after Stored Function with select query

Do I need to issue commit command after running the stored function with select query?
Yes, you do, in some cases (please read the discussion in the link below). The rule is: Always commit if you made change in DB (after DML commands), even with SELECT statement.
Use the COMMIT statement to end your current transaction and make permanent all changes performed in the transaction.
Read more: oracle - what statements need to be committed?
Thanks #Ben for the head up!
commit means "save the changes"
select statement does not change any data.
changing data can be done by Insert, update, delete statements (Data Manipulation language) .
You need to commit an sql statement only if you have performed a DML statement (INSERT, DELETE, UPDATE, MERGE) in your stored procedure. So, if you only queried the data, there is no need to commit.

How do I only select rows that have been committed - sql2008

How do I select all rows for a table, their isn't part of any transaction that hasn't committed yet?
Example:
Let's say,
Table T has 10 rows.
User A is doing a transaction with some queries:
INSERT INTO T (...)
SELECT ...
FROM T
// doing other queries
Now, here comes the tricky part:
What if User B, in the time between User A inserted the row and the transaction was committed, was updating a list in the system with a select on Table T.
I only want that the SELECT User B is using returned the 10 rows(all rows from the table, that can't later be rolled back). How do I do this, if it's even possible?
I have tried setting the isolationlevel on the transaction and adding "WITH(NOLOCK)" "WITH(READUNCOMMITTED)" to the query without any luck.
The query either return all 11 records or it's waiting for the transaction to commit, and that's not what I need.
Any tips is much appriciated, thanks.
You need to use (default) read committed isolation level and the READPAST hint to skip rows locked as they are not committed (rather than being blocked waiting for the locks to be released)
This does rely on the INSERT taking out rowlocks though. If it takes out page locks you will be back to being blocked. Example follows
Connection 1
IF OBJECT_ID('test_readpast') IS NULL
BEGIN
CREATE TABLE test_readpast(i INT PRIMARY KEY CLUSTERED)
INSERT INTO test_readpast VALUES (1)
END
BEGIN TRAN
INSERT INTO test_readpast
WITH(ROWLOCK)
--WITH(PAGLOCK)
VALUES (2)
SELECT * FROM sys.dm_tran_locks WHERE request_session_id=##SPID
WAITFOR DELAY '00:01';
ROLLBACK
Connection 2
SELECT i
FROM test_readpast WITH (readpast)
Snapshot isolation ?
Either I or else the three people who have answered early have misread/ misinterpreted your question, so I have given a link so you can determine for yourself.
Actually, read uncommitted and nolock are the same. They mean you get to see rows that have not been committed yet.
If you run at the default isolation level, read committed, you will not see new rows that have not been committed. This should work by default, but if you want to be sure, prefix your select with set transaction isolation level read committed.