public class LobStorageBackend extends Object implements LobStorageInterface
Using the system session
Why do we use the system session to store the data? Some LOB operations can take a very long time. If we did them on a normal session, we would be locking the LOB tables for long periods of time, which is extremely detrimental to the rest of the system. Perhaps when we shift to the MVStore engine, we can revisit this design decision (using the StreamStore, that is, no connection at all).
Locking
Normally, the locking order in H2 is: first lock the Session object, then lock the Database object. However, in the case of the LOB data, we are using the system session to store the data. If we locked the normal way, we see deadlocks caused by the following pattern:
Thread 1: locks normal session locks database waiting to lock system session Thread 2: locks system session waiting to lock database.So, in this class alone, we do two things: we have our very own dedicated session, the LOB session, and we take the locks in this order: first the Database object, and then the LOB session. Since we own the LOB session, no-one else can lock on it, and we are safe.
Modifier and Type | Class and Description |
---|---|
class |
LobStorageBackend.LobInputStream
An input stream that reads from a LOB.
|
Modifier and Type | Field and Description |
---|---|
static String |
LOB_DATA_TABLE
The name of the lob data table.
|
Constructor and Description |
---|
LobStorageBackend(Database database) |
Modifier and Type | Method and Description |
---|---|
ValueLobDb |
copyLob(ValueLobDb old,
int tableId,
long length)
Copy a lob.
|
Value |
createBlob(InputStream in,
long maxLength)
Create a BLOB object.
|
Value |
createClob(Reader reader,
long maxLength)
Create a CLOB object.
|
InputStream |
getInputStream(ValueLobDb lob,
byte[] hmac,
long byteCount)
Get the input stream for the given lob.
|
void |
init()
Initialize the lob storage.
|
boolean |
isReadOnly()
Whether the storage is read-only
|
void |
removeAllForTable(int tableId)
Remove all LOBs for this table.
|
void |
removeLob(ValueLobDb lob)
Delete a LOB (from the database, if it is stored there).
|
void |
setTable(ValueLobDb lob,
int table)
Set the table reference of this lob.
|
public static final String LOB_DATA_TABLE
public LobStorageBackend(Database database)
public void init()
LobStorageInterface
init
in interface LobStorageInterface
public void removeAllForTable(int tableId)
LobStorageInterface
removeAllForTable
in interface LobStorageInterface
tableId
- the table idpublic void removeLob(ValueLobDb lob)
LobStorageInterface
removeLob
in interface LobStorageInterface
lob
- the lobpublic InputStream getInputStream(ValueLobDb lob, byte[] hmac, long byteCount) throws IOException
LobStorageInterface
getInputStream
in interface LobStorageInterface
lob
- the lob idhmac
- the message authentication code (for remote input streams)byteCount
- the number of bytes to read, or -1 if not knownIOException
public boolean isReadOnly()
LobStorageInterface
isReadOnly
in interface LobStorageInterface
public ValueLobDb copyLob(ValueLobDb old, int tableId, long length)
LobStorageInterface
copyLob
in interface LobStorageInterface
old
- the old lobtableId
- the new table idlength
- the lengthpublic Value createBlob(InputStream in, long maxLength)
LobStorageInterface
createBlob
in interface LobStorageInterface
in
- the input streammaxLength
- the maximum length (-1 if not known)public Value createClob(Reader reader, long maxLength)
LobStorageInterface
createClob
in interface LobStorageInterface
reader
- the readermaxLength
- the maximum length (-1 if not known)public void setTable(ValueLobDb lob, int table)
LobStorageInterface
setTable
in interface LobStorageInterface
lob
- the lobtable
- the tableCopyright © 2017 JBoss by Red Hat. All rights reserved.