{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Transakcije v MariaDB/MySQL (transakcija A)\n", "\n", "### Pomožni elementi " ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "# pyODBC\n", "import pyodbc\n", "try:\n", " cn1.close()\n", "except:\n", " pass\n", "\n", "# MariaDB/MySQL\n", "conn = \"DRIVER={MySQL ODBC 5.3 Unicode Driver};SERVER=localhost;DATABASE=sandbox;UID=tup;PWD=tupvaje\"\n", "cn1 = pyodbc.connect(conn, autocommit=False)\n", "c1=cn1.cursor()" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Izpis rezultatov poizvedbe (pomožna funkcija)\n", "def tabela(rez):\n", " try:\n", " # Glava\n", " for g in rez.description:\n", " print(g[0],end=\"\\t\")\n", " print(\"\\n\"+\"-\"*31)\n", " # Vsebina\n", " for r in rez.fetchall():\n", " for a in r:\n", " print(a,end=\"\\t\")\n", " print() \n", " # Število vrstic\n", " print(\"Vseh vrstic je\", rez.rowcount)\n", " except Exception(e):\n", " pass" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Nadaljuj s pomožnimi elementi transakcije B" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Korak A1: nastavi transakcijske parametre za vse nadaljnje nove transakcije" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Timeout ob predolgem zaklepanju\n", "c1.execute(\"SET SESSION innodb_lock_wait_timeout = 5\") # Čas v sekundah\n", "# Preizkusite različne stopnje izolacije\n", "c1.execute(\"SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED\") \n", "# Začnemo novo transakcijo\n", "c1.commit()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Korak A2: kreiramo in napolnimo testno tabelo" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "c1.execute(\"DROP TABLE IF EXISTS rezervacija\")\n", "c1.execute(\"DROP TABLE IF EXISTS jadralec\") \n", "c1.execute(\"\"\"CREATE TABLE jadralec AS \n", " SELECT * from tup.jadralec\"\"\")\n", "c1.execute(\"ALTER TABLE jadralec ADD PRIMARY KEY(jid)\")\n", "#c1.execute(\"ALTER TABLE jadralec ENGINE MYISAM\") # Privzeto: InnoDB\n", "c1.commit();" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Korak A3: izpis vsebine tabele pred spremembo" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "jid\time\trating\tstarost\t\n", "-------------------------------\n", "22\tDarko\t7\t45.0\t\n", "29\tBorut\t1\t33.0\t\n", "31\tLojze\t8\t55.5\t\n", "32\tAndrej\t8\t25.5\t\n", "58\tRajko\t10\t35.0\t\n", "64\tHenrik\t7\t35.0\t\n", "71\tZdravko\t10\t16.0\t\n", "74\tHenrik\t9\t35.0\t\n", "85\tAnze\t3\t25.5\t\n", "95\tBine\t3\t63.5\t\n", "Vseh vrstic je 10\n" ] } ], "source": [ "c1.execute(\"SELECT * FROM jadralec\")\n", "tabela(c1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Nadaljuj s korakom B1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "-------------------------------\n", "# Branje neobstoječega podatka (dirty read)\n", "\n", "- stopnja izolacije mora biti vsaj `READ COMMITTED`\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Korak A4: sprememba tabele" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "try:\n", " c1.execute(\"UPDATE jadralec \\\n", " SET rating = 222 \\\n", " WHERE jid = 29\")\n", "except Exception as e:\n", " print(e)\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Korak A5: izpis vsebine tabele po spremembi" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "tabela(c1.execute(\"SELECT * FROM jadralec\"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Nadaljuj na koraku B5" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Korak A6: razveljavi spremembe in ponovno izpiši" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "jid\time\trating\tstarost\t\n", "-------------------------------\n", "22\tDarko\t7\t45.0\t\n", "29\tBorut\t1\t33.0\t\n", "31\tLojze\t8\t55.5\t\n", "32\tAndrej\t8\t25.5\t\n", "58\tRajko\t10\t35.0\t\n", "64\tHenrik\t7\t35.0\t\n", "71\tZdravko\t10\t16.0\t\n", "74\tHenrik\t9\t35.0\t\n", "85\tAnze\t3\t25.5\t\n", "95\tBine\t3\t63.5\t\n", "Vseh vrstic je 10\n" ] } ], "source": [ "c1.rollback()\n", "tabela(c1.execute(\"SELECT * FROM jadralec\"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Izgubljeno ažuriranje" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Korak A7: začetek nove transakcije in izpis ratinga" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n" ] } ], "source": [ "c1.rollback()\n", "c1.execute(\"\"\" SELECT rating \n", " FROM jadralec\n", " WHERE jid = 29\"\"\")\n", "rating = c1.fetchone()[0]\n", "print (rating)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Nadaljuj s korakom B4" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Korak A8: sprememba ratinga" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "c1.execute(\"UPDATE jadralec \\\n", " SET rating = ? \\\n", " WHERE jid = 29\", rating + 100)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Nadaljuj s korakom B5" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Korak A9: potrjevanje sprememb in izpis" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "c1.commit()\n", "tabela(c1.execute(\"SELECT * FROM jadralec\"))" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "------\n", "# Neponovljivo branje (`non-repeatable read`)\n", "- Potrebuje stopnjo izolacije najmanj `REPEATABLE READ` \n", "- Alernativno: `SELECT ... LOCK IN SHARE MODE` na kateri koli stopnji izolacije" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Korak A10: začetek transakcije in prvi izpis" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "c1.commit()\n", "tabela(c1.execute(\"SELECT * FROM jadralec\"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Nadaljuj s korakom B7" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Korak A11: nadaljevanje transakcije in drugi izpis" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "tabela(c1.execute(\"SELECT * FROM jadralec\"))" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "---------\n", "# Fantomsko branje (`phantom read`)\n", "## Potrebujemo `SERIALIZABLE`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Korak A12: začetek transakcije in prvi izpis" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "c1.commit()\n", "tabela(c1.execute(\"SELECT * FROM jadralec\"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Nadaljuj s korakom B8" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Korak A13: nadaljevanje transakcije in drugi izpis" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "tabela(c1.execute(\"SELECT * FROM jadralec\"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Če je stopnja izolacije nižja od `SERIALIZABLE` pride do pojava fantomske vrstice." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "----\n", "# Mrtva zanka" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "## Korak A14: prva sprememba in zaklepanje" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "c1.commit()\n", "c1.execute(\"SET innodb_lock_wait_timeout = 500\") # Daljši timeout samo za trenutno transakcijo\n", "c1.execute(\"UPDATE jadralec \\\n", " SET rating = ? \\\n", " WHERE jid = 22\", 122)" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "## Nadaljuj s korakom B9.\n", "## Korak A15: druga sprememba in zaklepanje" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "scrolled": true }, "outputs": [], "source": [ "c1.execute(\"UPDATE jadralec \\\n", " SET rating = ? \\\n", " WHERE jid = 29\", 129)\n", "c1.commit()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Čakamo na transakcijo B, dokler se ta ne prekine zaradi pojava mrtve zanke.\n", "## Nadaljuj s korakom B10." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Korak A16: izpis " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "tabela(c1.execute(\"SELECT * FROM jadralec\"))" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "anaconda-cloud": {}, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.3" } }, "nbformat": 4, "nbformat_minor": 1 }