@@ -104,7 +104,7 @@ <h2><a name="preface">Preface</a></h2>
104104
105105< ol >
106106 < li > < a target ="_blank " href ="https://www.python.org/ "> Python</ a > (3.6 preferred but 2.7 should work)</ li >
107- < li > cx_Oracle (version 7 preferred but 6.3 or later should work) and Oracle Instant Client Package - Basic (version 18 .3 preferred but 12.2 should work)
107+ < li > cx_Oracle (version 7.2 preferred but 6.3 or later should work, except for the section on Advanced Queuing which requires version 7.2 or later ) and Oracle Instant Client Package - Basic (version 19 .3 preferred but 18.3 or 12.2 should also work)
108108 < ul >
109109 < li > < a target ="_blank " href ="http://cx-oracle.readthedocs.io/en/latest/installation.html#installing-cx-oracle-on-linux "> Linux</ a > </ li >
110110 < li > < a target ="_blank " href ="http://cx-oracle.readthedocs.io/en/latest/installation.html#installing-cx-oracle-on-macos "> macOS</ a > - please note the special instructions for macOS in the link.</ li >
@@ -1976,7 +1976,7 @@ <h4>7.2 Fetching a CLOB as a string</h4>
19761976 end if;
19771977 end;""")
19781978
1979- # Create type
1979+ # Create a type
19801980print("Creating books type UDT_BOOK...")
19811981cur.execute("""
19821982 create type %s as object (
@@ -1988,38 +1988,47 @@ <h4>7.2 Fetching a CLOB as a string</h4>
19881988# Create queue table and queue and start the queue
19891989print("Creating queue table...")
19901990cur.callproc("dbms_aqadm.create_queue_table",
1991- (QUEUE_TABLE_NAME, BOOK_TYPE_NAME))
1991+ (QUEUE_TABLE_NAME, BOOK_TYPE_NAME))
19921992cur.callproc("dbms_aqadm.create_queue", (QUEUE_NAME, QUEUE_TABLE_NAME))
19931993cur.callproc("dbms_aqadm.start_queue", (QUEUE_NAME,))
19941994
1995- # Enqueue a few messages
19961995booksType = con.gettype(BOOK_TYPE_NAME)
1997- book1 = booksType.newobject()
1998- book1.TITLE = "The Fellowship of the Ring"
1999- book1.AUTHORS = "Tolkien, J.R.R."
2000- book1.PRICE = decimal.Decimal("10.99")
2001- book2 = booksType.newobject()
2002- book2.TITLE = "Harry Potter and the Philosopher's Stone"
2003- book2.AUTHORS = "Rowling, J.K."
2004- book2.PRICE = decimal.Decimal("7.99")
2005- options = con.enqoptions()
2006- messageProperties = con.msgproperties()
2007- for book in (book1, book2):
2008- print("Enqueuing book", book.TITLE)
2009- con.enq(QUEUE_NAME, options, messageProperties, book)
2010- con.commit()
1996+ queue = con.queue(QUEUE_NAME, booksType)
1997+
1998+ # Enqueue a few messages
1999+ print("Enqueuing messages...")
2000+
2001+ BOOK_DATA = [
2002+ ("The Fellowship of the Ring", "Tolkien, J.R.R.", decimal.Decimal("10.99")),
2003+ ("Harry Potter and the Philosopher's Stone", "Rowling, J.K.",
2004+ decimal.Decimal("7.99"))
2005+ ]
2006+
2007+ for title, authors, price in BOOK_DATA:
2008+ book = booksType.newobject()
2009+ book.TITLE = title
2010+ book.AUTHORS = authors
2011+ book.PRICE = price
2012+ print(title)
2013+ queue.enqOne(con.msgproperties(payload=book))
2014+ con.commit()
20112015
20122016# Dequeue the messages
2013- options = con.deqoptions()
2014- options.navigation = cx_Oracle.DEQ_FIRST_MSG
2015- options.wait = cx_Oracle.DEQ_NO_WAIT
2016- while con.deq(QUEUE_NAME, options, messageProperties, book):
2017- print("Dequeued book", book.TITLE)
2018- con.commit()
2017+ print("\nDequeuing messages...")
2018+ queue.deqOptions.wait = cx_Oracle.DEQ_NO_WAIT
2019+ while True:
2020+ props = queue.deqOne()
2021+ if not props:
2022+ break
2023+ print(props.payload.TITLE)
2024+ con.commit()
2025+
2026+ print("\nDone.")
20192027</ pre >
20202028
20212029< p > This file sets up Advanced Queuing using Oracle's DBMS_AQADM
2022- package. The queue is used for passing Oracle UDT_BOOK objects.</ p >
2030+ package. The queue is used for passing Oracle UDT_BOOK objects. The
2031+ file uses AQ interface features enhanced in cx_Oracle 7.2.</ p >
20232032
20242033< p > Run the file:</ p >
20252034
@@ -2030,14 +2039,37 @@ <h4>7.2 Fetching a CLOB as a string</h4>
20302039< p > To experiment, split the code into three files: one to create and
20312040start the queue, and two other files to queue and dequeue messages.
20322041Experiment running the queue and dequeue files concurrently in
2033- separate terminal windows. If you are stuck, look in the
2034- < code > solutions</ code > directory at the < code > aq-dequeue.py</ code > ,
2035- < code > aq-enqueue.py</ code > and < code > aq-queuestart.py</ code >
2036- files.</ p >
2037-
2038- < p > Try changing the dequeue options and mode. For example change the
2039- dequeue < code > options.wait</ code > value to
2040- < code > cx_Oracle.DEQ_WAIT_FOREVER</ code > .</ p >
2042+ separate terminal windows.</ p >
2043+
2044+ < p > Try removing the < code > commit()</ code > call in
2045+ < code > aq-dequeue.py</ code > . Now run < code > aq-enqueue.py</ code > once
2046+ and then < code > aq-dequeue.py</ code > several times. The same messages
2047+ will be available each time you try to dequeue them.</ p >
2048+
2049+ < p > Change < code > aq-dequeue.py</ code > to commit in a separate
2050+ transaction by changing the "visibility" setting:</ p >
2051+
2052+ < pre >
2053+ queue.deqOptions.visibility = cx_Oracle.DEQ_IMMEDIATE
2054+ </ pre >
2055+
2056+ < p > This gives the same behavior as the original code.</ p >
2057+
2058+ < p > Now change the options of enqueued messages so that they expire from the
2059+ queue if they have not been dequeued after four seconds:</ p >
2060+
2061+ < pre >
2062+ queue.enqOne(con.msgproperties(payload=book, expiration=4))
2063+ </ pre >
2064+
2065+ < p > Now run < code > aq-enqueue.py</ code > and wait four seconds before you
2066+ run < code > aq-dequeue.py</ code > . There should be no messages to
2067+ dequeue. </ p >
2068+
2069+ < p > If you are stuck, look in the < code > solutions</ code > directory at
2070+ the < code > aq-dequeue.py</ code > , < code > aq-enqueue.py</ code > and
2071+ < code > aq-queuestart.py</ code > files.</ p >
2072+
20412073
20422074</ ul >
20432075</ li >
0 commit comments