最近看mysql提供的支持java语言的驱动包底层实现,我对于mysql不了解,所以现在卡在了驱动包在向mysql server调用rollback、commit以及其他的操作时候是如何被mysql server接受得到指令,当然具体指令我也不清楚,但是大概了解类似于oracle的undo回滚一样,我是这么想的!今天在iteye主要是询问以下问题?
1.mysql server如何接受client端的指令
2.比如rollback操作,指令长啥样?
3.mysql server接受指令后,后续操作实现(宽泛点亦可,讲深篇幅不够,兴许还看不懂)
以下我是在看mysql底层包所查到的相关代码
public QueryResult executeQuery(final Query dQuery) throws QueryException {
log.finest("Executing streamed query: " + dQuery);
this.hasMoreResults = false;
final StreamedQueryPacket packet = new StreamedQueryPacket(dQuery);
try {
// make sure we are in a good state
packetFetcher.clearInputStream();
packet.send(writer);
} catch (IOException e) {
throw new QueryException("Could not send query: " + e.getMessage(),
-1,
SQLExceptionMapper.SQLStates.CONNECTION_EXCEPTION.getSqlState(),
e);
}
final RawPacket rawPacket;
final ResultPacket resultPacket;
try {
rawPacket = packetFetcher.getRawPacket();
resultPacket = ResultPacketFactory.createResultPacket(rawPacket);
} catch (IOException e) {
throw new QueryException("Could not read resultset: " + e.getMessage(),
-1,
SQLExceptionMapper.SQLStates.CONNECTION_EXCEPTION.getSqlState(),
e);
}
switch (resultPacket.getResultType()) {
case ERROR:
final ErrorPacket ep = (ErrorPacket) resultPacket;
checkIfCancelled();
log.warning("Could not execute query " + dQuery + ": " + ((ErrorPacket) resultPacket).getMessage());
throw new QueryException(ep.getMessage(),
ep.getErrorNumber(),
ep.getSqlState());
case OK:
final OKPacket okpacket = (OKPacket) resultPacket;
this.hasMoreResults = okpacket.getServerStatus().contains(ServerStatus.MORE_RESULTS_EXISTS);
final QueryResult updateResult = new DrizzleUpdateResult(okpacket.getAffectedRows(),
okpacket.getWarnings(),
okpacket.getMessage(),
okpacket.getInsertId());
log.fine("OK, " + okpacket.getAffectedRows());
return updateResult;
case RESULTSET:
log.fine("SELECT executed, fetching result set");
try {
return this.createDrizzleQueryResult((ResultSetPacket) resultPacket);
} catch (IOException e) {
throw new QueryException("Could not read result set: " + e.getMessage(),
-1,
SQLExceptionMapper.SQLStates.CONNECTION_EXCEPTION.getSqlState(),
e);
}
default:
log.severe("Could not parse result..." + resultPacket.getResultType());
throw new QueryException("Could not parse result", (short) -1, SQLExceptionMapper.SQLStates.INTERRUPTED_EXCEPTION.getSqlState());
}
}
public int send(final OutputStream ostream) throws IOException,
QueryException
{
if (query.length() > MAX_PACKET_LENGTH - HEADER_LENGTH)
{
// Query can not be sent on only one network packet
return sendSplittedQuery(ostream);
}
else
{
byte[] byteHeader = Utils.copyWithLength(
intToByteArray( query.length() + 1), 5);
byteHeader[3] = (byte) 0;
byteHeader[4] = (byte) 0x03;
ostream.write(byteHeader);
query.writeTo(ostream);
ostream.flush();
return 0;
}
}
private int sendSplittedQuery(OutputStream ostream) throws QueryException,
IOException
{
int remainingBytes = query.length();
int offset = 0;
int packetIndex = 0;
while (remainingBytes >= 0L)
{
int packLength = Math.min(remainingBytes, MAX_PACKET_LENGTH);
byte[] byteHeader = null;
if (packetIndex == 0)
{
byteHeader = Utils.copyWithLength(intToByteArray(packLength), 5);
// Add the command byte
byteHeader[4] = (byte) 0x03;
// And remove 1 byte from available data length
packLength -= 1;
}
else
{
byteHeader = Utils.copyWithLength(intToByteArray(packLength), 4);
}
byteHeader[3] = (byte) packetIndex;
if(log.isLoggable(Level.FINEST)) {
log.finest("Sending packet " + packetIndex + " with length = "
+ packLength + " / " + remainingBytes);
}
ostream.write(byteHeader);
if(log.isLoggable(Level.FINEST)) {
log.finest("Header is " + MySQLProtocol.hexdump(byteHeader, 0));
}
if (packLength > 0)
{
query.writeTo(ostream, offset, packLength);
}
ostream.flush();
if (remainingBytes >= MAX_PACKET_LENGTH)
{
remainingBytes -= packLength;
offset += packLength;
packetIndex++;
}
else
remainingBytes = -1;
}
return packetIndex;
}
2014年4月23日 15:18