001: /* Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com
002:
003: This file is part of the db4o open source object database.
004:
005: db4o is free software; you can redistribute it and/or modify it under
006: the terms of version 2 of the GNU General Public License as published
007: by the Free Software Foundation and as clarified by db4objects' GPL
008: interpretation policy, available at
009: http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
010: Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
011: Suite 350, San Mateo, CA 94403, USA.
012:
013: db4o is distributed in the hope that it will be useful, but WITHOUT ANY
014: WARRANTY; without even the implied warranty of MERCHANTABILITY or
015: FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
016: for more details.
017:
018: You should have received a copy of the GNU General Public License along
019: with this program; if not, write to the Free Software Foundation, Inc.,
020: 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
021: package com.db4o.internal.cs;
022:
023: import com.db4o.foundation.*;
024: import com.db4o.internal.*;
025: import com.db4o.internal.cs.messages.*;
026:
027: final class ClientTransaction extends Transaction {
028:
029: private final ClientObjectContainer i_client;
030:
031: protected Tree i_yapObjectsToGc;
032:
033: ClientTransaction(ClientObjectContainer container,
034: Transaction parentTransaction,
035: TransactionalReferenceSystem referenceSystem) {
036: super (container, parentTransaction, referenceSystem);
037: i_client = container;
038: }
039:
040: public void commit() {
041: commitTransactionListeners();
042: clearAll();
043: if (isSystemTransaction()) {
044: i_client.write(Msg.COMMIT_SYSTEMTRANS);
045: } else {
046: i_client.write(Msg.COMMIT);
047: i_client.expectedResponse(Msg.OK);
048: }
049: }
050:
051: protected void clear() {
052: removeYapObjectReferences();
053: }
054:
055: private void removeYapObjectReferences() {
056: if (i_yapObjectsToGc != null) {
057: i_yapObjectsToGc.traverse(new Visitor4() {
058: public void visit(Object a_object) {
059: ObjectReference yo = (ObjectReference) ((TreeIntObject) a_object)._object;
060: ClientTransaction.this .removeReference(yo);
061: }
062: });
063: }
064: i_yapObjectsToGc = null;
065: }
066:
067: public boolean delete(ObjectReference ref, int id, int cascade) {
068: if (!super .delete(ref, id, cascade)) {
069: return false;
070: }
071: MsgD msg = Msg.TA_DELETE.getWriterForInts(this , new int[] { id,
072: cascade });
073: i_client.writeBatchedMessage(msg);
074: return true;
075: }
076:
077: public boolean isDeleted(int a_id) {
078:
079: // This one really is a hack.
080: // It only helps to get information about the current
081: // transaction.
082:
083: // We need a better strategy for C/S concurrency behaviour.
084: MsgD msg = Msg.TA_IS_DELETED.getWriterForInt(this , a_id);
085: i_client.write(msg);
086: int res = i_client.expectedByteResponse(Msg.TA_IS_DELETED)
087: .readInt();
088: return res == 1;
089: }
090:
091: public final HardObjectReference getHardReferenceBySignature(
092: final long a_uuid, final byte[] a_signature) {
093: int messageLength = Const4.LONG_LENGTH + Const4.INT_LENGTH
094: + a_signature.length;
095: MsgD message = Msg.OBJECT_BY_UUID.getWriterForLength(this ,
096: messageLength);
097: message.writeLong(a_uuid);
098: message.writeBytes(a_signature);
099: i_client.write(message);
100: message = (MsgD) i_client.expectedResponse(Msg.OBJECT_BY_UUID);
101: int id = message.readInt();
102: if (id > 0) {
103: return container().getHardObjectReferenceById(this , id);
104: }
105: return HardObjectReference.INVALID;
106: }
107:
108: public void processDeletes() {
109: if (_delete != null) {
110: _delete.traverse(new Visitor4() {
111: public void visit(Object a_object) {
112: DeleteInfo info = (DeleteInfo) a_object;
113: if (info._reference != null) {
114: i_yapObjectsToGc = Tree.add(i_yapObjectsToGc,
115: new TreeIntObject(info._key,
116: info._reference));
117: }
118: }
119: });
120: }
121: _delete = null;
122: i_client.writeBatchedMessage(Msg.PROCESS_DELETES);
123: }
124:
125: public void rollback() {
126: i_yapObjectsToGc = null;
127: rollBackTransactionListeners();
128: clearAll();
129: }
130:
131: public void writeUpdateDeleteMembers(int a_id, ClassMetadata a_yc,
132: int a_type, int a_cascade) {
133: MsgD msg = Msg.WRITE_UPDATE_DELETE_MEMBERS.getWriterForInts(
134: this ,
135: new int[] { a_id, a_yc.getID(), a_type, a_cascade });
136: i_client.writeBatchedMessage(msg);
137: }
138:
139: }
|