diff -r b91c1cc4c893 lib/sqlalchemy/dialects/oracle/cx_oracle.py
--- a/lib/sqlalchemy/dialects/oracle/cx_oracle.py	Tue Nov 20 11:03:01 2012 -0500
+++ b/lib/sqlalchemy/dialects/oracle/cx_oracle.py	Tue Nov 20 19:11:42 2012 -0500
@@ -775,19 +775,35 @@
         id = random.randint(0, 2 ** 128)
         return (0x1234, "%032x" % id, "%032x" % 9)
 
+    def do_begin(self, connection):
+        connection.info.pop('cx_oracle_prepared', None)
+
     def do_begin_twophase(self, connection, xid):
         connection.connection.begin(*xid)
+        connection.info.pop('cx_oracle_prepared', None)
 
     def do_prepare_twophase(self, connection, xid):
-        connection.connection.prepare()
+        result = connection.connection.prepare()
+        connection.info['cx_oracle_prepared'] = result
 
     def do_rollback_twophase(self, connection, xid, is_prepared=True, recover=False):
         self.do_rollback(connection.connection)
+        connection.info.pop('cx_oracle_prepared', None)
 
     def do_commit_twophase(self, connection, xid, is_prepared=True, recover=False):
-        self.do_commit(connection.connection)
+        if not is_prepared:
+            self.do_commit(connection.connection)
+        else:
+            try:
+                oci_prepared = connection.info['cx_oracle_prepared']
+            except KeyError:
+                raise exc.InvalidRequestError("OCI connection was not 'prepared'")
+            else:
+                if oci_prepared:
+                    self.do_commit(connection.connection)
+                del connection.info['cx_oracle_prepared']
 
     def do_recover_twophase(self, connection):
-        pass
+        connection.info.pop('cx_oracle_prepared', None)
 
 dialect = OracleDialect_cx_oracle
