class OldValue {
        final long tid;
        final Object value;
        OldValue next;
        boolean useLast;

        public OldValue(long tid, Object value) {
            this.tid = tid;
            this.value = value;
        }
    }

    // 对于一个已经提交的值，如果当前事务因为隔离级别的原因读不到这个值，那么就返回SIGHTLESS
    public static final Object SIGHTLESS = new Object();

    private static final AtomicReferenceFieldUpdater<TransactionalValue, RowLock> rowLockUpdater = //
            AtomicReferenceFieldUpdater.newUpdater(TransactionalValue.class, RowLock.class, "rowLock");

    private static final RowLock NULL = new RowLock();

    private volatile RowLock rowLock = NULL;
    private Object value;

    public TransactionalValue(Object value) {
        this.value = value;
    }

    public TransactionalValue(Object value, AOTransaction t) {
        this.value = value;
        rowLock = new InsertRowLock(this);
        rowLock.tryLock(t, this, null); // insert的场景，old value是null
    }

    public void resetRowLock() {
        rowLock = NULL;
    }

    // 二级索引需要设置
    public void setTransaction(AOTransaction t) {
        if (rowLock == NULL) {
            rowLockUpdater.compareAndSet(this, NULL, new InsertRowLock(this));
        }
        if (rowLock.getTransaction() == null)
            rowLock.tryLock(t, this, value);
    }

    public AOTransaction getTransaction() {
        return rowLock.getTransaction();
    }

    Object getOldValue() {
        return rowLock.getOldValue();
    }

    public void setValue(Object value) {
        this.value = value;
    }

    @Override
    public Object getValue() {
        return value;
    }

    public Object getValue(AOTransaction transaction, StorageMap<?, ?> map) {
        // 先拿到LockOwner再用它获取信息，否则会产生并发问题
        LockOwner lockOwner = rowLock.getLockOwner();
        AOTransaction t = (AOTransaction) lockOwner.getTransaction();
        if (t != null) {
            // 如果拥有锁的事务是当前事务或当前事务的父事务，直接返回当前值
            if (t == transaction || t == transaction.getParentTransaction())
                return value;
        }
        // 如果事务当前执行的是更新类的语句那么自动通过READ_COMMITTED级别读取最新版本的记录
        int isolationLevel = transaction.isUpdateCommand() ? Transaction.IL_READ_COMMITTED
                : transaction.getIsolationLevel();
        switch (isolationLevel) {
        case Transaction.IL_READ_COMMITTED: {
            if (t != null) {
                if (t.isCommitted()) {
                    return value;
                } else {
                    if (lockOwner.getOldValue() == null)
                        return SIGHTLESS; // 刚刚insert但是还没有提交的记录
                    else
                        return lockOwner.getOldValue();
                }
            }
            return value;
        }
        case Transaction.IL_REPEATABLE_READ:
        case Transaction.IL_SERIALIZABLE: {
            long tid = transaction.getTransactionId();
            if (t != null && t.commitTimestamp > 0 && tid >= t.commitTimestamp) {
                return value;
            }
            ConcurrentHashMap<Object, Object> oldValueCache = map.getOldValueCache();
            OldValue oldValue = (OldValue) oldValueCache.get(this);
            if (oldValue != null) {
                if (tid >= oldValue.tid) {
                    if (t != null && lockOwner.getOldValue() != null)
                        return lockOwner.getOldValue();
                    else
                        return value;
                }
                while (oldValue != null) {
                    if (tid >= oldValue.tid)
                        return oldValue.value;
                    oldValue = oldValue.next;
                }
                return SIGHTLESS; // insert成功后的记录，旧事务看不到
            }
            if (t != null) {
                if (lockOwner.getOldValue() != null)
                    return lockOwner.getOldValue();
                else
                    return SIGHTLESS; // 刚刚insert但是还没有提交的记录
            } else {
                return value;
            }
        }
        case Transaction.IL_READ_UNCOMMITTED: {
            return value;
        }
        default:
            throw DbException.getInternalError();
        }
    }

    // 如果是0代表事务已经提交，对于已提交事务，只有在写入时才写入tid=0，
    // 读出来的时候为了不占用内存就不加tid字段了，这样每条已提交记录能省8个字节(long)的内存空间
    public long getTid() {
        AOTransaction t = rowLock.getTransaction();
        return t == null ? 0 : t.transactionId;
    }

    // 小于0：已经删除
    // 等于0：加锁失败
    // 大于0：加锁成功
    public int tryLock(AOTransaction t) {
        // 加一个if判断，避免创建对象
        if (rowLock == NULL) {
            rowLockUpdater.compareAndSet(this, NULL, new RowLock());
        }
        if (value == null && !isLocked(t)) // 已经删除了
            return -1;
        if (rowLock.tryLock(t, this, value))
            if (value == null) // 已经删除了
                return -1;
            else
                return 1;
        else
            return 0;
    }

    public boolean isLocked(AOTransaction t) {
        if (rowLock.getTransaction() == null)
            return false;
        else
            return rowLock.getTransaction() != t;
    }

    public int addWaitingTransaction(Object key, AOTransaction t) {
        return rowLock.addWaitingTransaction(key, rowLock.getTransaction(), t.getSession());
    }

    public void commit(boolean isInsert, StorageMap<?, ?> map) {<FILL_FUNCTION_BODY>

        AOTransaction t = rowLock.getTransaction();
        if (t == null)
            return;
        AOTransactionEngine te = t.transactionEngine;
        if (te.containsRepeatableReadTransactions()) {
            ConcurrentHashMap<Object, Object> oldValueCache = map.getOldValueCache();
            if (isInsert) {
                OldValue v = new OldValue(t.commitTimestamp, value);
                oldValueCache.put(this, v);
            } else {
                long maxTid = te.getMaxRepeatableReadTransactionId();
                OldValue old = (OldValue) oldValueCache.get(this);
                // 如果现有的版本已经足够给所有的可重复读事务使用了，那就不再加了
                if (old != null && old.tid > maxTid) {
                    old.useLast = true;
                    return;
                }
                OldValue v = new OldValue(t.commitTimestamp, value);
                if (old == null) {
                    OldValue ov = new OldValue(0, rowLock.getOldValue());
                    v.next = ov;
                } else if (old.useLast) {
                    OldValue ov = new OldValue(old.tid + 1, rowLock.getOldValue());
                    ov.next = old;
                    v.next = ov;
                } else {
                    v.next = old;
                }
                oldValueCache.put(this, v);
            }
        }
    
<no_super_class>