poggit / libasynql

Asynchronous MySQL access library for PocketMine plugins.
https://poggit.github.io/libasynql
Apache License 2.0
134 stars 44 forks source link

Add SQL Transaction #35

Open AkmalFairuz opened 4 years ago

AkmalFairuz commented 4 years ago

Is your feature request related to a problem? Please describe. I tried to make Payment System like EconomyAPI (/pay). A: doing pay to B B: receive pay from A It need 2 query ( Reduce money A Add money B ) , but when 1 query executed the server crash, A money reduced and B money not added.

I need startTransaction function and callback if query failed.

SOF3 commented 4 years ago

For now, your specific case can be done like this:

-- # :payer string
-- # :recipient string
-- # :amount int
UPDATE money SET amount = amount * IF(player = :payer, 1, -1) WHERE player IN (:payer, :recipient)

This is a very ugly hack, but before transactions get implemented, this method can successfully squeeze your queries into one.

AkmalFairuz commented 4 years ago

Hmm, Can you add LOCK TABLE & UNLOCK TABLE ?, Query will conflict when multi server using one MySQL Server

AkmalFairuz commented 4 years ago

For now, your specific case can be done like this:

-- # :payer string
-- # :recipient string
-- # :amount int
UPDATE money SET amount = amount * IF(player = :payer, 1, -1) WHERE player IN (:payer, :recipient)

This is a very ugly hack, but before transactions get implemented, this method can successfully squeeze your queries into one.

It only example. But i can't do this when result from query SELECT and the result must executed by code

SOF3 commented 4 years ago

Right now the best solution is to CREATE PROCEDURE or CREATE FUNCTION. Adding support for multiple queries breaks quite a lot of internals and is not trivial to implement.

matcracker commented 4 years ago

The problem could be simply resolved using AwaitGenerator.

  1. Wait until query reduced money to A
  2. Then add money to B.
SOF3 commented 4 years ago

The problem could be simply resolved using AwaitGenerator.

1. Wait until query reduced money to A

2. Then add money to B.

This has nothing to do with async. It is about the atomicness of transactions at the server side.