package fm.liu.timo.server.session.handler; import java.util.Collection; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import fm.liu.timo.config.ErrorCode; import fm.liu.timo.mysql.packet.OkPacket; import fm.liu.timo.net.connection.BackendConnection; import fm.liu.timo.server.session.Session; /** * @author liuhuanting */ public class AutoTransactionHandler extends SessionResultHandler { protected long affectedRows = 0; protected long insertId = 0; public AutoTransactionHandler(Session session, int count) { this.session = session; this.count = new AtomicInteger(count); } @Override public void ok(byte[] ok, BackendConnection con) { session.release(con); OkPacket p = new OkPacket(); p.read(ok); lock.lock(); try { affectedRows += p.affectedRows; if (p.insertId > 0) { insertId = (insertId == 0) ? p.insertId : Math.min(insertId, p.insertId); } } finally { lock.unlock(); } if (decrement()) { if (this.failed()) { session.clear(); onError(); return; } try { p.packetId = ++packetId;// OK_PACKET p.affectedRows = affectedRows; if (insertId > 0) { p.insertId = insertId; session.getFront().setLastInsertId(insertId); } prepareSendCommit(p); } catch (Exception e) { setFail(ErrorCode.ER_YES, e.toString()); if (decrement()) { onError(); } } } } private void prepareSendCommit(OkPacket ok) { Collection<BackendConnection> cons = session.availableConnections(); if (cons.size() == session.getConnections().size()) { commit(cons); } else { session.clear(); session.getFront().writeErrMessage(ErrorCode.ER_YES, "some connection already closed when commit"); } } private void commit(Collection<BackendConnection> cons) { ResultHandler handler = new CommitHandler(session, cons); cons.forEach(c -> c.query("commit", handler)); } @Override public void error(byte[] error, BackendConnection con) { session.clear(); session.getFront().write(error); } @Override public void field(byte[] header, List<byte[]> fields, byte[] eof, BackendConnection con) {} @Override public void row(byte[] row, BackendConnection con) {} @Override public void eof(byte[] eof, BackendConnection con) {} }