Databases

NAVIGATION
CATEGORIES
REFERRENCE
LINKS
  • Multiple SELECTs (and single SELECT) and TRANSACTION ?

    10 answers - 988 bytes - related search similar search Add To My Delicious Add To My Stumble Upon Add To My Google Mark Add To My Facebook Add To My Digg Add To My Reddit

    Hi All,
    While using SQLite dll Version 3.3.4 on Windows
    - Multiple threads/processes access SQLite database,
    - Each thread does some SELECTs, INSERTs or UPDATEs.
    Scenario 1
    If action of some user needs to execute multiple SELECT statements
    (read-only, no plan to write), it needs to start explicit transaction to get
    consistent reads across read-only multiple statements.
    Q1. Which one is preferable -BEGIN TRANSACTIN or BEGIN IMMEDIATE ?
    Q2. What is preferable After Multiple SELECT statements gets over -CMMIT
    or RLLBACK ? (note: no change is made since only SELECTs)
    Scenario 2
    If action of some user needs to execute only single SELECT statement
    (read-only, no plan to write)
    As what I understand, there is no point in wrapping such single SELECT in
    transaction.
    Q3. What is preferable, whether to start explicit transaction or not for
    single SELECT ?
    I truly appreciate any help/guidance.
    Rohit
  • No.1 | | 1053 bytes | |

    RohitPatel9999 <@public.gmane.org>
    wrote:
    Scenario 1
    If action of some user needs to execute multiple SELECT statements
    (read-only, no plan to write), it needs to start explicit transaction
    to get consistent reads across read-only multiple statements.

    Q1. Which one is preferable -BEGIN TRANSACTIN or BEGIN IMMEDIATE
    ?

    BEGIN IMMEDIATE would block other readers. Don't use it unless you plan
    to write.

    Q2. What is preferable After Multiple SELECT statements gets over ->
    CMMIT or RLLBACK ? (note: no change is made since only SELECTs)

    I don't think it matters.

    Scenario 2
    If action of some user needs to execute only single SELECT statement
    (read-only, no plan to write)

    As what I understand, there is no point in wrapping such single
    SELECT in transaction.

    Right. There's no harm either.

    Q3. What is preferable, whether to start explicit transaction or not
    for single SELECT ?

    Doesn't matter.

    Igor Tandetnik
  • No.2 | | 627 bytes | |

    "Igor Tandetnik" <itandetnik (AT) mvps (DOT) orgwrote:

    RohitPatel9999 <@public.gmane.org>
    wrote:
    Scenario 1
    If action of some user needs to execute multiple SELECT statements
    (read-only, no plan to write), it needs to start explicit transaction
    to get consistent reads across read-only multiple statements.

    Q1. Which one is preferable -BEGIN TRANSACTIN or BEGIN IMMEDIATE
    ?

    BEGIN IMMEDIATE would block other readers. Don't use it unless you plan
    to write.

    BEGIN IMMEDIATE blocks writers, not readers. I believe it's
    what he wants.

    Regards
  • No.3 | | 1598 bytes | |

    Kurt Welgehausen <kwel-axnCwrHX1KE (AT) public (DOT) gmane.orgwrote:
    "Igor Tandetnik" <itandetnik-fH9DrAxc5Jo (AT) public (DOT) gmane.orgwrote:
    >
    >RohitPatel9999
    ><@public.gmane.org>
    >wrote:

    Scenario 1
    If action of some user needs to execute multiple SELECT statements
    (read-only, no plan to write), it needs to start explicit
    transaction to get consistent reads across read-only multiple
    statements.

    Q1. Which one is preferable -BEGIN TRANSACTIN or BEGIN
    IMMEDIATE ?
    >>

    >BEGIN IMMEDIATE would block other readers. Don't use it unless you
    >plan
    >to write.
    >

    BEGIN IMMEDIATE blocks writers, not readers. I believe it's
    what he wants.

    You are correct, BEGIN IMMEDIATE does not block readers. Still, it
    acquires a RESERVED lock which is overkill for a read-only transaction.
    A SELECT statement acquires a SHARED lock which block writers anyway.

    Normally, a writer acquires RESERVED lock, then writes modifications
    into the memory cache. when a transaction is committed, or when the
    memory cache becomes full and the data needs to be spilled to disk, does
    the writer need to acquire EXCLUSIVE lock before actually writing to a
    physical file.

    By having a reader transaction grab RESERVED lock, you would prevent the
    writer from even starting its work with the memory cache. This could
    hurt performance, for no apparent reason.

    Igor Tandetnik
  • No.4 | | 843 bytes | |

    Thanks a lot for the answers.

    Still I have a doubt (and a question).

    Quote from SQLite Document ()

    "After a BEGIN IMMEDIATE, you are guaranteed that no other thread or process
    will be able to write to the database or do a BEGIN IMMEDIATE or BEGIN
    EXCLUSIVE."

    As I understand, it means after issuing BEGIN IMMIDIATE for read-only
    SELECT(s), no other process can do BEGIN IMMIDIATE even if its for read-only
    purpose. Even new reader will be blocked if it tries to do BEGIN IMMEDIATE.

    So if I use BEGIN IMMEDIATE for multiple SELECTs, no other reader
    thread/process can do BEGIN IMMEDIATE even if it has read-only SELECTs

    If this is correct, for multiple SELECT statements (read-only, no plan to
    write),

    Which one is preferable -BEGIN TRANSACTIN or BEGIN IMMEDIATE ?

    Rohit
  • No.5 | | 479 bytes | |

    Thanks for the answer and clarification.

    BEGIN IMMEDIATE blocks writers, not readers.

    I think, BEGIN IMMEDIATE surely blocks writers.
    And also blocks new reader(s) if any new reader tries to do BEGIN IMMEDIATE.

    Is this correct ?

    Ref: Quote from SQLite Document
    ()
    "After a BEGIN IMMEDIATE, you are guaranteed that no other thread or process
    will be able to write to the database or do a BEGIN IMMEDIATE or BEGIN
    EXCLUSIVE."

    Rohit
  • No.6 | | 658 bytes | |

    RohitPatel9999 <@public.gmane.org>
    wrote:
    As I understand, it means after issuing BEGIN IMMIDIATE for read-only
    SELECT(s), no other process can do BEGIN IMMIDIATE even if its for
    read-only purpose. Even new reader will be blocked if it tries to do
    BEGIN IMMEDIATE.

    Right. Readers aren't supposed to do BEGIN IMMEDIATE - it's pointless
    and harmful. Writers may, but don't really have to either.

    If this is correct, for multiple SELECT statements (read-only, no
    plan to write),

    Which one is preferable -BEGIN TRANSACTIN or BEGIN IMMEDIATE ?

    BEGIN TRANSACTIN

    Igor Tandetnik
  • No.7 | | 562 bytes | |

    Thanks for clearing doubt.

    Now question is

    While using SQLite dll Version 3.3.4 on Windows
    - Multiple threads/processes access SQLite database,
    - Each thread does some SELECTs, INSERTs or UPDATEs.

    Wrapping all read-only SELECEs with BEGIN TRANSACTIN
    and using BEGIN EXCLUSIVE to wrap all UPDATEs or INSERTs (including their
    related SELECTs),

    Are their possibilities of writer starvation ?
    And if yes, what is the preferable solution ? (I mean what is the better
    approach to handle that)

    Thanks again.
    Rohit
  • No.8 | | 771 bytes | |

    RohitPatel9999 <@public.gmane.org>
    wrote:
    While using SQLite dll Version 3.3.4 on Windows
    - Multiple threads/processes access SQLite database,
    - Each thread does some SELECTs, INSERTs or UPDATEs.

    Wrapping all read-only SELECEs with BEGIN TRANSACTIN
    and using BEGIN EXCLUSIVE to wrap all UPDATEs or INSERTs (including
    their related SELECTs),

    Are their possibilities of writer starvation ?

    With big enough time-out set up, there should not be. In the process of
    acquiring EXCLUSIVE lock, SQLite first acquires PENDING lock which
    allows existing readers to proceed but does not allow any new readers
    in. all the readers clear, the writer acquires EXCLUSIVE lock and
    can begin writing.

    Igor Tandetnik
  • No.9 | | 1038 bytes | |

    It depends upon your application. For it to function optimally you
    should make each transaction on your application an SQL transaction,
    commit it on success or rollback if there is a problem. In that way you
    make each transaction atomic and maintain the integrity of your database.

    Since Sqlite locks the entire database when it is being modified,
    transactions which modify the database can be made exclusive.

    RohitPatel9999 wrote:
    Thanks for clearing doubt.

    Now question is

    While using SQLite dll Version 3.3.4 on Windows
    - Multiple threads/processes access SQLite database,
    - Each thread does some SELECTs, INSERTs or UPDATEs.

    Wrapping all read-only SELECEs with BEGIN TRANSACTIN
    and using BEGIN EXCLUSIVE to wrap all UPDATEs or INSERTs (including their
    related SELECTs),

    Are their possibilities of writer starvation ?
    And if yes, what is the preferable solution ? (I mean what is the better
    approach to handle that)

    Thanks again.
    Rohit
  • No.10 | | 2025 bytes | |

    Many thanks for helping.

    While using SQLite dll Version 3.3.4 on Windows
    - Multiple threads/processes access SQLite database,
    - Each thread does some SELECTs, INSERTs or UPDATEs.

    If for some single SELECT (where user input is used in SQL statement, so to
    avoid SQL injection),
    sqlite3_prepare()/sqlite3_bind()/sqlite3_step()/sqlite3_finalize() are
    used
    then in that case
    Q1. Which one is preferable -BEGIN TRANSACTIN or BEGIN IMMEDIATE ?

    Q2. In the sample code below, if I remove two statements containing "BEGIN
    TRANSACTIN;" and "CMMIT TRANSACTIN;" then for how long lock will be
    acquired i.e. at which point of time lock will be acquired and which point
    of time lock will be released ?

    Please throw some light on that.

    Thanks
    Rohit

    /* Sample code */
    sqlite3* pDB;
    sqlite3_stmt* pStmt;
    char* szError = 0;
    char* szTail = 0;
    if( sqlite3_open("test.db", &pDB) != SQLITEK )
    {
    printf("Couldn't open the database.\n");
    exit(1);
    }

    string name;
    /* get from user input */
    name = "ABCD"; // for testing

    nRet = sqlite3_exec(pDB, "BEGIN TRANSACTIN;", 0, 0, &szError);
    <<<<<<<<<<

    const char* szSQL = "SELECT id, name, birthdate FRM table1 WHERE name = ?;"
    ;
    nRet = sqlite3_bind_text(mpVM, nParam, szValue, -1, SQLITE_TRANSIENT);

    if( sqlite3_prepare(pDB, szSQL, -1, &pStmt, &szTail) != SQLITEK )
    throw "sqlite3_prepare Failed";

    if ( sqlite3_step(pStmt) == SQLITE_DNE )
    {
    int i=0;
    int empid = sqlite3_column_int(pStmt, ++i);
    string name = (const char*) sqlite3_column_text(pStmt, ++i);
    double birthdate = sqlite3_column_double(pStmt, ++i);

    /* print something */
    std::cout << id << "-" << name << "-" << birthdate << endl;
    }

    nRet = sqlite3_finalize(pStmt);

    nRet = sqlite3_exec(pDB, "CMMIT TRANSACTIN;", 0, 0, &szError);
    <<<<<<<<<<

Re: Multiple SELECTs (and single SELECT) and TRANSACTION ?


max 4000 letters.
Your nickname that display:
In order to stop the spam: 8 + 7 =
QUESTION ON "Databases"

EMSDN.COM