1 /* 2 * Copyright (c) 2010, 2021, Oracle and/or its affiliates. 3 * All rights reserved. Use is subject to license terms. 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License, version 2.0, 7 * as published by the Free Software Foundation. 8 * 9 * This program is also distributed with certain software (including 10 * but not limited to OpenSSL) that is licensed under separate terms, 11 * as designated in a particular file or component or in included license 12 * documentation. The authors of MySQL hereby grant you an additional 13 * permission to link the program and your derivative works with the 14 * separately licensed software that they have included with MySQL. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License, version 2.0, for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program; if not, write to the Free Software 23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 24 */ 25 26 package com.mysql.clusterj.bindings; 27 28 import com.mysql.cluster.ndbj.NdbApiException; 29 import com.mysql.cluster.ndbj.NdbOperation.AbortOption; 30 import com.mysql.cluster.ndbj.NdbOperation; 31 import com.mysql.cluster.ndbj.NdbScanOperation; 32 import com.mysql.cluster.ndbj.NdbTransaction; 33 import com.mysql.clusterj.ClusterJDatastoreException; 34 import com.mysql.clusterj.core.store.ClusterTransaction; 35 import com.mysql.clusterj.core.store.Index; 36 import com.mysql.clusterj.core.store.IndexOperation; 37 import com.mysql.clusterj.core.store.IndexScanOperation; 38 import com.mysql.clusterj.core.store.Operation; 39 import com.mysql.clusterj.core.store.ScanOperation; 40 import com.mysql.clusterj.core.store.Table; 41 import com.mysql.clusterj.core.util.I18NHelper; 42 import com.mysql.clusterj.core.util.Logger; 43 import com.mysql.clusterj.core.util.LoggerFactoryService; 44 import java.util.ArrayList; 45 import java.util.List; 46 47 /** 48 * 49 */ 50 class ClusterTransactionImpl implements ClusterTransaction { 51 52 /** My message translator */ 53 static final I18NHelper local = I18NHelper 54 .getInstance(ClusterTransactionImpl.class); 55 56 /** My logger */ 57 static final Logger logger = LoggerFactoryService.getFactory() 58 .getInstance(ClusterTransactionImpl.class); 59 60 protected NdbTransaction ndbTransaction; 61 private List<Runnable> postExecuteCallbacks = new ArrayList<Runnable>(); 62 ClusterTransactionImpl(NdbTransaction ndbTransaction)63 public ClusterTransactionImpl(NdbTransaction ndbTransaction) { 64 this.ndbTransaction = ndbTransaction; 65 } 66 close()67 public void close() { 68 ndbTransaction.close(); 69 } 70 executeCommit()71 public void executeCommit() { 72 handlePendingPostExecuteCallbacks(); 73 try { 74 ndbTransaction.executeCommit(); 75 } catch (NdbApiException ndbApiException) { 76 throw new ClusterJDatastoreException(local.message("ERR_Datastore"), 77 ndbApiException); 78 } 79 } 80 executeCommit(boolean abort, boolean force)81 public void executeCommit(boolean abort, boolean force) { 82 handlePendingPostExecuteCallbacks(); 83 AbortOption abortOption = abort?AbortOption.AbortOnError:AbortOption.AO_IgnoreError; 84 try { 85 ndbTransaction.execute(NdbTransaction.ExecType.Commit, 86 abortOption, force); 87 } catch (NdbApiException ndbApiException) { 88 throw new ClusterJDatastoreException(local.message("ERR_Datastore"), 89 ndbApiException); 90 } 91 } 92 executeNoCommit(boolean abort, boolean force)93 public void executeNoCommit(boolean abort, boolean force) { 94 AbortOption abortOption = abort?AbortOption.AbortOnError:AbortOption.AO_IgnoreError; 95 try { 96 ndbTransaction.execute(NdbTransaction.ExecType.NoCommit, 97 abortOption, force); 98 performPostExecuteCallbacks(); 99 } catch (NdbApiException ndbApiException) { 100 throw new ClusterJDatastoreException(local.message("ERR_Datastore"), 101 ndbApiException); 102 } 103 } 104 executeNoCommit()105 public void executeNoCommit() { 106 try { 107 ndbTransaction.executeNoCommit(); 108 performPostExecuteCallbacks(); 109 } catch (NdbApiException ndbApiException) { 110 throw new ClusterJDatastoreException(local.message("ERR_Datastore"), 111 ndbApiException); 112 } 113 } 114 executeRollback()115 public void executeRollback() { 116 try { 117 clearPostExecuteCallbacks(); 118 ndbTransaction.executeRollback(); 119 } catch (NdbApiException ndbApiException) { 120 throw new ClusterJDatastoreException(local.message("ERR_Datastore"), 121 ndbApiException); 122 } 123 } 124 getDeleteOperation(Table storeTable)125 public Operation getDeleteOperation(Table storeTable) { 126 try { 127 return new OperationImpl(ndbTransaction.getDeleteOperation(storeTable.getName()), this); 128 } catch (NdbApiException ndbApiException) { 129 throw new ClusterJDatastoreException(local.message("ERR_Datastore"), 130 ndbApiException); 131 } 132 } 133 getInsertOperation(Table storeTable)134 public Operation getInsertOperation(Table storeTable) { 135 try { 136 return new OperationImpl(ndbTransaction.getInsertOperation(storeTable.getName()), this); 137 } catch (NdbApiException ndbApiException) { 138 throw new ClusterJDatastoreException(local.message("ERR_Datastore"), 139 ndbApiException); 140 } 141 } 142 getSelectIndexScanOperation(Index storeIndex, Table storeTable)143 public IndexScanOperation getSelectIndexScanOperation(Index storeIndex, Table storeTable) { 144 try { 145 return new IndexScanOperationImpl( 146 ndbTransaction.getSelectIndexScanOperation(storeIndex.getName(), storeTable.getName()), this); 147 } catch (NdbApiException ndbApiException) { 148 throw new ClusterJDatastoreException(local.message("ERR_Datastore"), 149 ndbApiException); 150 } 151 } 152 getSelectOperation(Table storeTable)153 public Operation getSelectOperation(Table storeTable) { 154 try { 155 return new OperationImpl(ndbTransaction.getSelectOperation(storeTable.getName()), this); 156 } catch (NdbApiException ndbApiException) { 157 throw new ClusterJDatastoreException(local.message("ERR_Datastore"), 158 ndbApiException); 159 } 160 } 161 getSelectScanOperation(Table storeTable)162 public ScanOperation getSelectScanOperation(Table storeTable) { 163 try { 164 return new ScanOperationImpl( 165 ndbTransaction.getSelectScanOperation(storeTable.getName()), this); 166 } catch (NdbApiException ndbApiException) { 167 throw new ClusterJDatastoreException(local.message("ERR_Datastore"), 168 ndbApiException); 169 } 170 } 171 getSelectScanOperationLockModeExclusiveScanFlagKeyInfo(Table storeTable)172 public ScanOperation getSelectScanOperationLockModeExclusiveScanFlagKeyInfo(Table storeTable) { 173 try { 174 return new ScanOperationImpl( 175 ndbTransaction.getSelectScanOperation(storeTable.getName(), 176 NdbOperation.LockMode.LM_Exclusive, 177 NdbScanOperation.ScanFlag.KEY_INFO, 0,0), this); 178 } catch (NdbApiException ndbApiException) { 179 throw new ClusterJDatastoreException(local.message("ERR_Datastore"), 180 ndbApiException); 181 } 182 } 183 getSelectUniqueOperation(Index storeIndex, Table storeTable)184 public IndexOperation getSelectUniqueOperation(Index storeIndex, Table storeTable) { 185 try { 186 return new IndexOperationImpl( 187 ndbTransaction.getSelectUniqueOperation(storeIndex.getName(), storeTable.getName()), this); 188 } catch (NdbApiException ndbApiException) { 189 throw new ClusterJDatastoreException(local.message("ERR_Datastore"), 190 ndbApiException); 191 } 192 } 193 getUpdateOperation(Table storeTable)194 public Operation getUpdateOperation(Table storeTable) { 195 try { 196 return new OperationImpl(ndbTransaction.getUpdateOperation(storeTable.getName()), this); 197 } catch (NdbApiException ndbApiException) { 198 throw new ClusterJDatastoreException(local.message("ERR_Datastore"), 199 ndbApiException); 200 } 201 } 202 getWriteOperation(Table storeTable)203 public Operation getWriteOperation(Table storeTable) { 204 try { 205 return new OperationImpl(ndbTransaction.getWriteOperation(storeTable.getName()), this); 206 } catch (NdbApiException ndbApiException) { 207 throw new ClusterJDatastoreException(local.message("ERR_Datastore"), 208 ndbApiException); 209 } 210 } 211 postExecuteCallback(Runnable callback)212 public void postExecuteCallback(Runnable callback) { 213 postExecuteCallbacks.add(callback); 214 } 215 clearPostExecuteCallbacks()216 private void clearPostExecuteCallbacks() { 217 postExecuteCallbacks.clear(); 218 } 219 handlePendingPostExecuteCallbacks()220 private void handlePendingPostExecuteCallbacks() { 221 // if any pending postExecuteCallbacks, flush via executeNoCommit 222 if (!postExecuteCallbacks.isEmpty()) { 223 executeNoCommit(); 224 } 225 } 226 performPostExecuteCallbacks()227 private void performPostExecuteCallbacks() { 228 try { 229 for (Runnable runnable: postExecuteCallbacks) { 230 try { 231 runnable.run(); 232 } catch (Throwable t) { 233 throw new ClusterJDatastoreException( 234 local.message("ERR_Datastore"), t); 235 } 236 } 237 } finally { 238 clearPostExecuteCallbacks(); 239 } 240 } 241 242 }