29 |
29 |
30 from logilab.common.deprecation import deprecated |
30 from logilab.common.deprecation import deprecated |
31 from logilab.common.textutils import unormalize |
31 from logilab.common.textutils import unormalize |
32 from logilab.common.registry import objectify_predicate |
32 from logilab.common.registry import objectify_predicate |
33 |
33 |
34 from cubicweb import UnknownEid, QueryError, schema |
34 from cubicweb import UnknownEid, QueryError, schema, server |
35 from cubicweb.req import RequestSessionBase |
35 from cubicweb.req import RequestSessionBase |
36 from cubicweb.dbapi import ConnectionProperties |
36 from cubicweb.dbapi import ConnectionProperties |
37 from cubicweb.utils import make_uid |
37 from cubicweb.utils import make_uid |
38 from cubicweb.rqlrewrite import RQLRewriter |
38 from cubicweb.rqlrewrite import RQLRewriter |
39 from cubicweb.server import ShuttingDown |
39 from cubicweb.server import ShuttingDown |
937 return |
937 return |
938 # on rollback, an operation should have the following state |
938 # on rollback, an operation should have the following state |
939 # information: |
939 # information: |
940 # - processed by the precommit/commit event or not |
940 # - processed by the precommit/commit event or not |
941 # - if processed, is it the failed operation |
941 # - if processed, is it the failed operation |
|
942 debug = server.DEBUG & server.DBG_OPS |
942 try: |
943 try: |
943 # by default, operations are executed with security turned off |
944 # by default, operations are executed with security turned off |
944 with security_enabled(self, False, False): |
945 with security_enabled(self, False, False): |
945 processed = [] |
946 processed = [] |
946 self.commit_state = 'precommit' |
947 self.commit_state = 'precommit' |
|
948 if debug: |
|
949 print self.commit_state, '*' * 20 |
947 try: |
950 try: |
948 while self.pending_operations: |
951 while self.pending_operations: |
949 operation = self.pending_operations.pop(0) |
952 operation = self.pending_operations.pop(0) |
950 operation.processed = 'precommit' |
953 operation.processed = 'precommit' |
951 processed.append(operation) |
954 processed.append(operation) |
|
955 if debug: |
|
956 print operation |
952 operation.handle_event('precommit_event') |
957 operation.handle_event('precommit_event') |
953 self.pending_operations[:] = processed |
958 self.pending_operations[:] = processed |
954 self.debug('precommit session %s done', self.id) |
959 self.debug('precommit session %s done', self.id) |
955 except BaseException: |
960 except BaseException: |
956 # if error on [pre]commit: |
961 # if error on [pre]commit: |
962 # that seems more natural than not calling rollback_event |
967 # that seems more natural than not calling rollback_event |
963 # for processed operations, and allow generic rollback |
968 # for processed operations, and allow generic rollback |
964 # instead of having to implements rollback, revertprecommit |
969 # instead of having to implements rollback, revertprecommit |
965 # and revertcommit, that will be enough in mont case. |
970 # and revertcommit, that will be enough in mont case. |
966 operation.failed = True |
971 operation.failed = True |
|
972 if debug: |
|
973 print self.commit_state, '*' * 20 |
967 for operation in reversed(processed): |
974 for operation in reversed(processed): |
|
975 if debug: |
|
976 print operation |
968 try: |
977 try: |
969 operation.handle_event('revertprecommit_event') |
978 operation.handle_event('revertprecommit_event') |
970 except BaseException: |
979 except BaseException: |
971 self.critical('error while reverting precommit', |
980 self.critical('error while reverting precommit', |
972 exc_info=True) |
981 exc_info=True) |
975 self.pending_operations[:] = processed + self.pending_operations |
984 self.pending_operations[:] = processed + self.pending_operations |
976 self.rollback(free_cnxset) |
985 self.rollback(free_cnxset) |
977 raise |
986 raise |
978 self.cnxset.commit() |
987 self.cnxset.commit() |
979 self.commit_state = 'postcommit' |
988 self.commit_state = 'postcommit' |
|
989 if debug: |
|
990 print self.commit_state, '*' * 20 |
980 while self.pending_operations: |
991 while self.pending_operations: |
981 operation = self.pending_operations.pop(0) |
992 operation = self.pending_operations.pop(0) |
|
993 if debug: |
|
994 print operation |
982 operation.processed = 'postcommit' |
995 operation.processed = 'postcommit' |
983 try: |
996 try: |
984 operation.handle_event('postcommit_event') |
997 operation.handle_event('postcommit_event') |
985 except BaseException: |
998 except BaseException: |
986 self.critical('error while postcommit', |
999 self.critical('error while postcommit', |