Project

General

Profile

6995-6129c.patch

Radu Apetrii, 02/08/2023 09:44 AM

Download (29.6 KB)

View differences:

new/src/com/goldencode/p2j/persist/Persistence.java 2023-02-08 14:13:43 +0000
584 584
**     OM  20221103          New class names for FQLPreprocessor, FQLExpression, FQLBundle, and FQLCache.
585 585
**     CA  20221109          Implemented runtime for EXCEPT/FIELDS options - only NO-LOCK records are loaded 
586 586
**                           as 'partial/incomplete'.
587
**     RAA 20230208          Removed the checks for no-undo as they are no longer necessary. 
587 588
*/
588 589

  
589 590
/*
......
2871 2872
         
2872 2873
         Query query = getQuery(local, fql, 0, 0, values, false);
2873 2874
         count = query.executeUpdate(session);
2874
         if (noUndo)
2875
         {
2876
            session.noUndoBulkUpdate(query);
2877
         }
2878 2875
         
2879 2876
         if (LOG.isLoggable(Level.FINER))
2880 2877
         {
......
3477 3474
         
3478 3475
         rc = query.executeUpdate(session);
3479 3476
         
3480
         if (noUndo)
3481
         {
3482
            session.noUndoBulkUpdate(query);
3483
         }
3484
         
3485 3477
         if (LOG.isLoggable(Level.FINER))
3486 3478
         {
3487 3479
            LOG.log(Level.FINER, "[" + sql + "] rc = " + rc);
new/src/com/goldencode/p2j/persist/TempTableHelper.java 2023-02-08 14:30:56 +0000
54 54
**     OM  20221027          H2 dialect requires that the index names to be truly unique.
55 55
**     SVL 20230110          P2JIndex.components() provides direct access to the components array in order to
56 56
**                           improve performance.
57
**     RAA 20230208          Added "no-undo" as a temp table postfix in constructor.
57 58
*/
58 59

  
59 60
/*
......
391 392
      String primaryIndexName = null;
392 393
      String primarySqlIndexName = null;
393 394
      
394
      String createTemporaryTablePostfix = dialect.getCreateTemporaryTablePostfix();
395
      String createTemporaryTablePostfix = dialect.getCreateTemporaryTablePostfix(false);
396
      String createTemporaryNoUndoTablePostfix = dialect.getCreateTemporaryTablePostfix(true);
395 397
      String delimiter = dialect.getDelimiter();
396 398
      String suffix = createTemporaryTablePostfix + delimiter;
397 399
      while (databaseIndexes.hasNext())
......
622 624
         {
623 625
            table.append(tab).append("primary key (").append(Session.PK).append(")\n");
624 626
         }
625
         table.append(")").append(createTemporaryTablePostfix).append(delimiter);
627
         
628
         table.append(")").append(createTemporaryTablePostfix);
629
         if (dmo.noUndo)
630
         {
631
            table.append(createTemporaryNoUndoTablePostfix);
632
         }
633
         
634
         table.append(delimiter);
626 635
         
627 636
         String tableDDL = table.toString();
628 637
         ddlCreateTables.add(tableDDL);
new/src/com/goldencode/p2j/persist/dialect/Dialect.java 2023-02-08 14:31:55 +0000
95 95
**     SVL 20230110          P2JIndex.components() provides direct access to the components array in order to
96 96
**                           improve performance.
97 97
**     ECF 20230127          Added resolveBooleanConstant method.
98
**     RAA 20230208          Modified function for creating a temp table postfix. Depending on the parameter,
99
**                           it can resume its initial purpose or it can return the keyword specific to
100
**                           no-undo temp-tables.
98 101
*/
99 102

  
100 103
/*
......
1312 1315
   /**
1313 1316
    * Return the ending of the DDL statement that creates a temporary table.
1314 1317
    *
1318
    * @param   noUndo
1319
    *          If {@code true}, this function will return the keyword specific to no-undo temp-tables.
1320
    *           
1315 1321
    * @return  A string representing the ending of the DDL statement that creates a temporary
1316 1322
    *          table, if any, or empty string otherwise.
1317 1323
    */
1318
   public abstract String getCreateTemporaryTablePostfix();
1324
   public abstract String getCreateTemporaryTablePostfix(boolean noUndo);
1319 1325
   
1320 1326
   /**
1321 1327
    * Returns the beginning of the DDL statement for creating an index.
new/src/com/goldencode/p2j/persist/dialect/MariaDbLenientDialect.java 2023-02-08 14:24:51 +0000
14 14
**     BS  20230126 Added support for SAVE CACHE.
15 15
**     ECF 20230127 Data type adjustment for SAVE CACHE.
16 16
**     OM  20230131 Code cleanup.
17
**     RAA 20230208 Added parameter for getCreateTemporaryTablePostfix.
17 18
*/
18 19

  
19 20
/*
......
1471 1472
   /**
1472 1473
    * Return the ending of the DDL statement that creates a temporary table.
1473 1474
    *
1475
    * @param   noUndo
1476
    *          This parameter is not used at the moment. The intention was to generate a keyword for
1477
    *          no-undo tables. Only {@link P2JH2Dialect} benefits from this parameter.
1478
    * 
1474 1479
    * @return  A string representing the ending of the DDL statement that creates a temporary table, if any,
1475 1480
    *          or empty string otherwise.
1476 1481
    *
1477 1482
    * @see <a href="https://mariadb.com/kb/en/create-table/#transactional">CREATE TABLE TRANSACTIONAL</a>
1478 1483
    */
1479 1484
   @Override
1480
   public String getCreateTemporaryTablePostfix()
1485
   public String getCreateTemporaryTablePostfix(boolean noUndo)
1481 1486
   {
1482 1487
      return " transactional";
1483 1488
   }
new/src/com/goldencode/p2j/persist/dialect/P2JH2Dialect.java 2023-02-08 14:26:29 +0000
106 106
**     OM  20221026          Excluded table name from index name by default. It will be added as needed by
107 107
**                           dialects.
108 108
**     RAA 20230109          Overrided methods getSequenceSetValString() and getSequenceCurrValString().
109
**     RAA 20230208          Overrided method for returning the postfix of a no-undo temp-table.
109 110
*/
110 111

  
111 112
/*
......
1321 1322
   /**
1322 1323
    * Return the ending of the DDL statement that creates a temporary table.
1323 1324
    *
1325
    * @param   noUndo
1326
    *          Parameter that indicates what keyword should be returned. The choices are "transactional"
1327
    *          and "noundo".
1328
    *
1324 1329
    * @return  A string representing the ending of the DDL statement that creates a temporary
1325 1330
    *          table.
1326 1331
    */
1327 1332
   @Override
1328
   public String getCreateTemporaryTablePostfix()
1333
   public String getCreateTemporaryTablePostfix(boolean noUndo)
1329 1334
   {
1330
      return " transactional";
1335
      if (!noUndo)
1336
      {
1337
         return " transactional";
1338
      }
1339
      
1340
      return " noundo";
1331 1341
   }
1332 1342
   
1333 1343
   /**
new/src/com/goldencode/p2j/persist/dialect/P2JPostgreSQLDialect.java 2023-02-08 14:27:50 +0000
123 123
**     OM  20221026          Excluded table name from index name by default. It will be added as needed by
124 124
**                           dialects.
125 125
**     RAA 20230109          Overrided method getSequenceSetValString().
126
**     RAA 20230208          Added parameter for getCreateTemporaryTablePostfix.
126 127
*/
127 128

  
128 129
/*
......
1679 1680
   /**
1680 1681
    * Return the ending of the DDL statement that creates a temporary table.
1681 1682
    *
1683
    * @param   noUndo
1684
    *          This parameter is not used at the moment. The intention was to generate a keyword for
1685
    *          no-undo tables. Only {@link P2JH2Dialect} benefits from this parameter.
1686
    *
1682 1687
    * @return  A string representing the ending of the DDL statement that creates a temporary
1683 1688
    *          table.
1684 1689
    */
1685 1690
   @Override
1686
   public String getCreateTemporaryTablePostfix()
1691
   public String getCreateTemporaryTablePostfix(boolean noUndo)
1687 1692
   {
1688 1693
      return " on commit drop";
1689 1694
   }
new/src/com/goldencode/p2j/persist/dialect/P2JSQLServer2008Dialect.java 2023-02-08 14:28:55 +0000
43 43
**     RAA 20230109 Overrided method getSequenceSetValString().
44 44
**     SVL 20230110 P2JIndex.components() provides direct access to the components array in order to improve
45 45
**                  performance.
46
**     RAA 20230208 Added parameter for getCreateTemporaryTablePostfix.
46 47
*/
47 48

  
48 49
/*
......
1163 1164
   /**
1164 1165
    * Return the ending of the DDL statement that creates a temporary table.
1165 1166
    *
1167
    * @param   noUndo
1168
    *          This parameter is not used at the moment. The intention was to generate a keyword for
1169
    *          no-undo tables. Only {@link P2JH2Dialect} benefits from this parameter.
1170
    *
1166 1171
    * @return  An empty string. This dialect does not support this feature.
1167 1172
    */
1168 1173
   @Override
1169
   public String getCreateTemporaryTablePostfix()
1174
   public String getCreateTemporaryTablePostfix(boolean noUndo)
1170 1175
   {
1171 1176
      return "";
1172 1177
   }
new/src/com/goldencode/p2j/persist/orm/SQLRedo.java 1970-01-01 00:00:00 +0000
1
/*
2
** Module   : SQLRedo.java
3
** Abstract : Redoable SQL operation for NO-UNDO temp-table use.
4
**
5
** Copyright (c) 2020, Golden Code Development Corporation.
6
**
7
** -#- -I- --Date-- ---------------------------------Description---------------------------------
8
** 001 ECF 20200413 First revision. A redoable SQL operation for use with NO-UNDO temp-tables.
9
*/
10

  
11
/*
12
** This program is free software: you can redistribute it and/or modify
13
** it under the terms of the GNU Affero General Public License as
14
** published by the Free Software Foundation, either version 3 of the
15
** License, or (at your option) any later version.
16
**
17
** This program is distributed in the hope that it will be useful,
18
** but WITHOUT ANY WARRANTY; without even the implied warranty of
19
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
** GNU Affero General Public License for more details.
21
**
22
** You may find a copy of the GNU Affero GPL version 3 at the following
23
** location: https://www.gnu.org/licenses/agpl-3.0.en.html
24
**
25
** Additional terms under GNU Affero GPL version 3 section 7:
26
**
27
**   Under Section 7 of the GNU Affero GPL version 3, the following additional
28
**   terms apply to the works covered under the License.  These additional terms
29
**   are non-permissive additional terms allowed under Section 7 of the GNU
30
**   Affero GPL version 3 and may not be removed by you.
31
**
32
**   0. Attribution Requirement.
33
**
34
**     You must preserve all legal notices or author attributions in the covered
35
**     work or Appropriate Legal Notices displayed by works containing the covered
36
**     work.  You may not remove from the covered work any author or developer
37
**     credit already included within the covered work.
38
**
39
**   1. No License To Use Trademarks.
40
**
41
**     This license does not grant any license or rights to use the trademarks
42
**     Golden Code, FWD, any Golden Code or FWD logo, or any other trademarks
43
**     of Golden Code Development Corporation. You are not authorized to use the
44
**     name Golden Code, FWD, or the names of any author or contributor, for
45
**     publicity purposes without written authorization.
46
**
47
**   2. No Misrepresentation of Affiliation.
48
**
49
**     You may not represent yourself as Golden Code Development Corporation or FWD.
50
**
51
**     You may not represent yourself for publicity purposes as associated with
52
**     Golden Code Development Corporation, FWD, or any author or contributor to
53
**     the covered work, without written authorization.
54
**
55
**   3. No Misrepresentation of Source or Origin.
56
**
57
**     You may not represent the covered work as solely your work.  All modified
58
**     versions of the covered work must be marked in a reasonable way to make it
59
**     clear that the modified work is not originating from Golden Code Development
60
**     Corporation or FWD.  All modified versions must contain the notices of
61
**     attribution required in this license.
62
*/
63

  
64
package com.goldencode.p2j.persist.orm;
65

  
66
import com.goldencode.p2j.persist.*;
67

  
68
/**
69
 * This class re-applies a single database insert, update, or [bulk] delete action, in order to
70
 * redo such an action that was undone by a database rollback (savepoint or full transaction).
71
 * It is needed to implement the NO-UNDO feature of 4GL temp-tables.
72
 * <p>
73
 * The top-level class is abstract. To use this class, instantiate one of the specialized,
74
 * concrete, inner subclasses.
75
 */
76
abstract class SQLRedo
77
{
78
   /** Lambda which performs the redo action and possibly throws a persistence exception */
79
   private final ThrowingAction action;
80
   
81
   /** Flag indicating that the original action was rolled back and redo is required */
82
   private boolean active = false;
83
   
84
   /**
85
    * Constructor.
86
    * 
87
    * @param   action
88
    *          Lambda which performs the redo action and possibly throws a persistence exception.
89
    */
90
   protected SQLRedo(ThrowingAction action)
91
   {
92
      this.action = action;
93
   }
94
   
95
   /**
96
    * Mark this redo action as active, meaning the original action which this object was undone
97
    * by a full or sub-transaction rollback, and needs to be re-applied. If an instance of this
98
    * class is not marked active, it is a no-op.
99
    */
100
   void setActive()
101
   {
102
      active = true;
103
   }
104
   
105
   /**
106
    * Perform this object's redo action, if it was marked active.
107
    * 
108
    * @throws  PersistenceException
109
    *          if there is an error executing the action.
110
    */
111
   void perform()
112
   throws PersistenceException
113
   {
114
      if (active)
115
      {
116
         action.run();
117
      }
118
   }
119
   
120
   /**
121
    * A no-arg functional interface which throws PersistenceException, to avoid having to handle
122
    * this exception in every defined lambda expression.
123
    */
124
   @FunctionalInterface
125
   protected interface ThrowingAction
126
   {
127
      /**
128
       * Run a SQL operation.
129
       * 
130
       * @throws  PersistenceException
131
       *          if a persistence error occurs.
132
       */
133
      public void run()
134
      throws PersistenceException;
135
   }
136
   
137
   /**
138
    * An insert action for a single record.
139
    */
140
   static class Insert
141
   extends SQLRedo
142
   {
143
      Insert(Persister persister, BaseRecord dmo)
144
      {
145
         super(() -> persister.insert(dmo));
146
      }
147
   }
148
   
149
   /**
150
    * An update action for a single record.
151
    */
152
   static class Update
153
   extends SQLRedo
154
   {
155
      Update(Persister persister, BaseRecord dmo)
156
      {
157
         super(() -> persister.update(dmo));
158
      }
159
   }
160
   
161
   /**
162
    * A delete action for a single record.
163
    */
164
   static class Delete
165
   extends SQLRedo
166
   {
167
      Delete(Persister persister, Class<? extends BaseRecord> dmoClass, Long id)
168
      {
169
         super(() -> persister.delete(dmoClass, id));
170
      }
171
   }
172
   
173
   /**
174
    * A bulk action (delete or update) which affects 0 or more records.
175
    */
176
   static class BulkUpdate
177
   extends SQLRedo
178
   {
179
      BulkUpdate(Session session, SQLQuery query)
180
      {
181
         super(() -> query.executeUpdate(session));
182
      }
183
   }
184
}
new/src/com/goldencode/p2j/persist/orm/SavepointManager.java 2023-02-08 14:29:25 +0000
26 26
**                  Added JMX for profiling NO-UNDO operation tracing.
27 27
**     CA  20220630 Cleanup the 'redoable' list once the full transaction ends.
28 28
**     CA  20230116 Avoid creating a collection until is needed.
29
**     RAA 20230208 Removed all code that was linked to redo operations as it is no longer needed.
29 30
*/
30 31

  
31 32
/*
......
150 151
   /** Stack of block states which coincide with transaction block scopes */
151 152
   private final Deque<Block> blocks = new ArrayDeque<>();
152 153
   
153
   /** The list of redoable insert, update, and delete SQL operations for NO-UNDO temp-tables */
154
   private final List<SQLRedo> redoable = new ArrayList<>(64);
155
   
156 154
   /** Database session used for savepoint processing */
157 155
   private Session session = null;
158 156
   
......
331 329
   
332 330
   /**
333 331
    * Roll back the active block, which entails rolling back any savepoint, rolling up tracked
334
    * resources, and marking any tracked undoable records as stale and any redoable operations
335
    * as active.
332
    * resources, and marking any tracked undoable records as stale.
336 333
    * 
337 334
    * @param   transaction
338 335
    *          {@code true} if the current block is a full transaction; {@code false} if it is
......
461 458
   }
462 459
   
463 460
   /**
464
    * Create a redoable SQL operation for the insertion of a NO-UNDO record into the database. If
465
    * the original operation is rolled back at the database, this operation must be re-applied
466
    * after the full or sub-transaction which rolled it back completes.
467
    * 
468
    * @param   dmo
469
    *          DMO which was updated.
470
    */
471
   void noUndoInsert(BaseRecord dmo)
472
   {
473
      if (session != null && activeBlock != null)
474
      {
475
         NO_UNDO_TRACE.timer(() -> {
476
            SQLRedo.Insert redo = new SQLRedo.Insert(session.getPersister(), dmo.deepCopy());
477
            redoable.add(redo);
478
         });
479
      }
480
   }
481
   
482
   /**
483
    * Create a redoable SQL operation for the update of a NO-UNDO record in the database. If
484
    * the original operation is rolled back at the database, this operation must be re-applied
485
    * after the full or sub-transaction which rolled it back completes.
486
    * 
487
    * @param   dmo
488
    *          DMO which was updated.
489
    */
490
   void noUndoUpdate(BaseRecord dmo)
491
   {
492
      if (session != null && activeBlock != null && dmo.checkState(CHANGED))
493
      {
494
         NO_UNDO_TRACE.timer(() -> {
495
            SQLRedo.Update redo = new SQLRedo.Update(session.getPersister(), dmo.deepCopy());
496
            redoable.add(redo);
497
         });
498
      }
499
   }
500
   
501
   /**
502
    * Create a redoable SQL operation for the deletion of a NO-UNDO record from the database. If
503
    * the original operation is rolled back at the database, this operation must be re-applied
504
    * after the full or sub-transaction which rolled it back completes.
505
    * 
506
    * @param   dmoClass
507
    *          Implementation class of the DMO which was deleted.
508
    * @param   id
509
    *          Primary key of the record which was deleted.
510
    */
511
   void noUndoDelete(Class<? extends BaseRecord> dmoClass, Long id)
512
   {
513
      if (session != null && activeBlock != null)
514
      {
515
         NO_UNDO_TRACE.timer(() -> {
516
            SQLRedo.Delete redo = new SQLRedo.Delete(session.getPersister(), dmoClass, id);
517
            redoable.add(redo);
518
         });
519
      }
520
   }
521
   
522
   /**
523
    * Create a redoable SQL operation for the bulk update of zero or more NO-UNDO records in
524
    * the database. The operation may be an update or a delete. If the original operation is
525
    * rolled back at the database, this operation must be re-applied after the full or
526
    * sub-transaction which rolled it back completes.
527
    * 
528
    * @param   query
529
    *          SQL query which performed the original bulk operation.
530
    */
531
   void noUndoBulkUpdate(SQLQuery query)
532
   {
533
      if (session != null && activeBlock != null)
534
      {
535
         NO_UNDO_TRACE.timer(() -> {
536
            SQLRedo.BulkUpdate redo = new SQLRedo.BulkUpdate(session, query);
537
            redoable.add(redo);
538
         });
539
      }
540
   }
541
   
542
   /**
543 461
    * Set a savepoint in the active block and in every previous block which has not yet had one set,
544 462
    * except for the outermost (which represents the full transaction block).
545 463
    * <p>
......
622 540
   private void prepareBlock()
623 541
   {
624 542
      parentBlock = blocks.peek();
625
      activeBlock = new Block(blocks.size(), redoable);
543
      activeBlock = new Block(blocks.size());
626 544
      blocks.push(activeBlock);
627 545
      
628 546
      if (debug)
......
643 561
      Block lastActiveBlock = activeBlock;
644 562
      Block popped = blocks.pop();
645 563
      
646
      // reapply undone changes for any NO-UNDO temporary tables
647
      // let the noUndoRolledBack flag check here to avoid profiling disabled redo
648
      if (session != null && lastActiveBlock != null && lastActiveBlock.noUndoRolledBack)
649
      {
650
         REDO.timer(() -> lastActiveBlock.maybeReapplyNoUndo(session));
651
      }
652
      
653 564
      // reactivate the next block in the stack (if any)
654 565
      activeBlock = blocks.isEmpty() ? null : blocks.pop();
655 566
      parentBlock = blocks.isEmpty() ? null : blocks.peek();
......
667 578
      {
668 579
         // full transaction is finished, deactivate savepoint manager (i.e., remove session)
669 580
         this.session = null;
670
         if (redoable != null)
671
         {
672
            redoable.clear();
673
         }
674 581
      }
675 582
   }
676 583
   
......
735 642
      /** Records which have been changed in the scope of this block */
736 643
      private Set<BaseRecord> changed = null;
737 644
      
738
      /** List of SQL redo helpers for NO-UNDO records, shared among all blocks */
739
      private final List<SQLRedo> redoable;
740
      
741
      /** Starting index for this block in full transaction redoable list */
742
      private final int redoHead;
743
      
744 645
      /** Database savepoint for a sub-transaction block ({@code null} for full transaction */
745 646
      private Savepoint savepoint = null;
746 647
      
747
      /** Have we rolled back NO-UNDO changes in this block which will need to be re-applied? */
748
      private boolean noUndoRolledBack = false;
749
      
750 648
      /**
751 649
       * Constructor.
752 650
       */
753
      Block(int txLevel, List<SQLRedo> redoable)
651
      Block(int txLevel)
754 652
      {
755 653
         this.txLevel = txLevel;
756
         this.redoable = redoable;
757
         this.redoHead = redoable.size();
758 654
      }
759 655
      
760 656
      /**
......
808 704
      }
809 705
      
810 706
      /**
811
       * Roll back changes to undoable records and activate redoable actions for NO-UNDO records.
707
       * Roll back changes to undoable records.
812 708
       */
813 709
      void rollback()
814 710
      throws PersistenceException
815 711
      {
816 712
         if (txLevel > 0 && savepoint == null)
817 713
         {
818
            // no DMOs were updated within this block, so nothing to undo nor mark for deferred redo
714
            // no DMOs were updated within this block, so nothing to undo
819 715
            return;
820 716
         }
821 717
         
......
826 722
               dmo.rollback(txLevel);
827 723
            }
828 724
         }
829
         
830
         int redoSize = redoable.size();
831
         if (redoSize > redoHead)
832
         {
833
            noUndoRolledBack = true;
834
            
835
            for (int i = redoHead; i < redoSize; i++)
836
            {
837
               redoable.get(i).setActive();
838
            }
839
         }
840 725
      }
841 726
      
842 727
      /** Notify the FastFind cache that the changed tables need to be invalidated. */
......
868 753
      }
869 754
      
870 755
      /**
871
       * Indicate whether this block is tracking any NO-UNDO records.
872
       * 
873
       * @return  {@code true} if there are any NO-UNDO records associated with this block, else
874
       *          {@code false}.
875
       */
876
      boolean isTrackingNoUndo()
877
      {
878
         return redoable.size() > redoHead;
879
      }
880
      
881
      /**
882
       * Re-apply any changes to no-undo records which were rolled back in the most recent
883
       * savepoint or full transaction.
884
       * 
885
       * @param   session
886
       *          Database session helper object.
887
       */
888
      void maybeReapplyNoUndo(Session session)
889
      {
890
         if (!noUndoRolledBack)
891
         {
892
            // nothing to do
893
            return;
894
         }
895
         
896
         boolean fullTx = false;
897
         
898
         try
899
         {
900
            // if the active block was a full transaction block, we need to start a separate,
901
            // full, transaction to re-roll forward any NO-UNDO changes that were rolled back
902
            // at the database; for sub-transactions, we will still be in the context of the
903
            // existing transaction
904
            if (txLevel == 0)
905
            {
906
               fullTx = session.beginTransaction(null);
907
            }
908
            
909
            int redoSize = redoable.size();
910
            for (int i = redoHead; i < redoSize; i++)
911
            {
912
               SQLRedo redo = redoable.get(i);
913
               redo.perform();
914
            }
915
            
916
            if (fullTx)
917
            {
918
               session.commit();
919
            }
920
         }
921
         catch (PersistenceException exc)
922
         {
923
            if (fullTx)
924
            {
925
               if (log.isLoggable(Level.SEVERE))
926
               {
927
                  log.log(Level.SEVERE, "Error reapplying rolled back NO-UNDO changes", exc);
928
               }
929
               
930
               try
931
               {
932
                  session.rollback();
933
               }
934
               catch (PersistenceException exc1)
935
               {
936
                  if (log.isLoggable(Level.SEVERE))
937
                  {
938
                     log.log(Level.SEVERE, "Error rolling back NO-UNDO reapply transaction", exc1);
939
                  }
940
               }
941
            }
942
            
943
            // TODO: proper error handling
944
            throw new StopConditionException(exc);
945
         }
946
      }
947
      
948
      /**
949 756
       * Get a debug text representation of this object.
950 757
       * 
951 758
       * @return  Text representation of state.
new/src/com/goldencode/p2j/persist/orm/Session.java 2023-02-08 14:29:58 +0000
38 38
**                  the database, and not just returned.
39 39
**     CA  20230104 If a cached record is incomplete, preserve the dirty properties when loading the full
40 40
**                  record.
41
**     RAA 20230208 Removed everything that had to do with redo operations as it is no longer needed.
41 42
*/
42 43

  
43 44
/*
......
743 744
      boolean wasNew = dmo.checkState(NEW);
744 745
      boolean wasDirty = wasNew || dmo.isDirty();
745 746
      
746
      if (wasDirty && savepointManager != null)
747
      {
748
         // undoable events must be logged with the DMO before the insert/update takes place, because
749
         // the logging might trigger a database savepoint to be lazily set, and this savepoint must
750
         // include the insert/update
751
         
752
         if (dmo.checkState(NOUNDO))
753
         {
754
            if (wasNew)
755
            {
756
               savepointManager.noUndoInsert(dmo);
757
            }
758
            else
759
            {
760
               savepointManager.noUndoUpdate(dmo);
761
            }
762
         }
763
      }
764
      
765 747
      // decide what to do with the record
766 748
      if (wasNew)
767 749
      {
......
873 855
      
874 856
      // attempt to delete the record if it is not newly created (i.e., as of yet unflushed)
875 857
      if (!dmo.checkState(NEW))
876
      {
877
         if (savepointManager != null && dmo.checkState(NOUNDO))
878
         {
879
            savepointManager.noUndoDelete(dmo.getClass(), dmo.primaryKey());
880
         }
881
         
858
      {  
882 859
         success = persister.delete(dmo);
883 860
      }
884 861
      
......
957 934
         @SuppressWarnings("unchecked")
958 935
         Class<? extends Record> recordClass = (Class<? extends Record>) dmoClass;
959 936
         
960
         if (savepointManager != null && cached != null && cached.checkState(NOUNDO))
961
         {
962
            savepointManager.noUndoDelete(recordClass, id);
963
         }
964
         
965 937
         success = persister.delete(recordClass, id);
966 938
      }
967 939
      
......
1518 1490
   }
1519 1491
   
1520 1492
   /**
1521
    * Create a redoable SQL operation for the bulk update of zero or more NO-UNDO records in
1522
    * the database. The operation may be an update or a delete. If the original operation is
1523
    * rolled back at the database, this operation must be re-applied after the full or
1524
    * sub-transaction which rolled it back completes.
1525
    * <p>
1526
    * This method delegates to the session's savepoint manager, if any, whose responsibility it
1527
    * is to track and apply the corresponding redoable SQL operation at the appropriate moment.
1528
    * 
1529
    * @param   query
1530
    *          FQL query which performed the original bulk operation.
1531
    */
1532
   public void noUndoBulkUpdate(Query query)
1533
   {
1534
      noUndoBulkUpdate(query.getSqlQuery());
1535
   }
1536
   
1537
   /**
1538
    * Create a redoable SQL operation for the bulk update of zero or more NO-UNDO records in
1539
    * the database. The operation may be an update or a delete. If the original operation is
1540
    * rolled back at the database, this operation must be re-applied after the full or
1541
    * sub-transaction which rolled it back completes.
1542
    * <p>
1543
    * This method delegates to the session's savepoint manager, if any, whose responsibility it
1544
    * is to track and apply the corresponding redoable SQL operation at the appropriate moment.
1545
    * 
1546
    * @param   query
1547
    *          SQL query which performed the original bulk operation.
1548
    */
1549
   public void noUndoBulkUpdate(SQLQuery query)
1550
   {
1551
      if (savepointManager != null)
1552
      {
1553
         savepointManager.noUndoBulkUpdate(query);
1554
      }
1555
   }
1556
   
1557
   /**
1558 1493
    * Get the zero-based transaction block nesting level, where 0 indicates the current block is a full
1559 1494
    * transaction block, 1 indicates the current block is the first level of nested subtransaction, and so
1560 1495
    * on. Note that this includes only blocks with transaction properties; no-transaction blocks which may