mysql事务里if_MYSQL If语句在事务中导致错误

我有以下MYSQL查询:

START TRANSACTION;

SELECT sport_id INTO @a FROM sports WHERE sport_id = 2 FOR UPDATE;

UPDATE sports SET sport_name = 'Table Tennis' WHERE sport_id = @a;

if (@a > 1) then

COMMIT;

ELSE

ROLLBACK;

END IF;

问题是它在if语句中返回一个错误:

#1064 – You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘if (@a > 1) then COMMIT’ at line 1

我看过堆栈溢出,有一个answer showing a similar query,用几乎相同的方式编写,但它们使用的是没有@符号的变量.删除我的查询@不能解决问题.

这只是一个使用MYSQL尝试一些事务的测试查询,因此查询看起来有点无意义.我有点卡住了.

最佳答案 MySQL无法识别以关键字IF开头的语句和有效的SQL语句.

IF语句仅在复合语句的上下文中起作用(即,在BEGIN和END之间包含的语句块.目前,复合语句仅在存储程序(存储过程,函数或触发器)的上下文中受支持.

如需测试,请尝试……

DELIMITER //

CREATE PROCEDURE usp_test_transaction()

BEGIN

DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK;

START TRANSACTION;

-- whatever DML operations and SELECT statements you want to perform go here

IF (1=1) THEN

COMMIT;

ELSE

ROLLBACK;

END IF;

END//

DELIMITER ;

CALL usp_test_transaction;

(注意:我在这里并不主张在存储过程中处理事务.我个人的偏好是不要这样做,而是处理更高级别的事务.但上面的例子应该有效;我相信MySQL确实支持调用START TRANSACTION ,存储过程的上下文中的COMMIT和ROLLBACK.)

在使用`tornado_mysql`的连接池时,可以使用以下代码来执行事务: ```python import tornado.ioloop import tornado.web import tornado.gen import tornado_mysql class MainHandler(tornado.web.RequestHandler): async def get(self): db = self.application.db async with db.pool.acquire() as conn: async with conn.cursor() as cur: try: await cur.execute("START TRANSACTION") await cur.execute("INSERT INTO table_name (column1, column2) VALUES (%s, %s)", (value1, value2)) await cur.execute("UPDATE table_name SET column3 = %s WHERE id = %s", (value3, id)) await cur.execute("COMMIT") self.write("Transaction completed successfully!") except: await cur.execute("ROLLBACK") self.write("Transaction failed") class Application(tornado.web.Application): def __init__(self): handlers = [ (r"/", MainHandler), ] self.db = tornado_mysql.Pool( dict(host='localhost', port=3306, user='root', passwd='password', db='database_name'), max_size=10, autocommit=True ) super(Application, self).__init__(handlers) if __name__ == "__main__": app = Application() app.listen(8888) tornado.ioloop.IOLoop.current().start() ``` 在上述代码,我们首先创建了一个`Pool`对象,它包含了数据库的连接参数和连接池的最大连接数。然后,在我们的请求处理程序,我们通过`pool.acquire()`方法获取一个连接。我们使用`async with`来确保在完成事务后自动释放该连接。 在使用的连接上创建一个`cursor`来执行事务的SQL语句。在使用`try/except`块执行SQL语句时,如果任何一个语句失败,我们将立即回滚整个事务。如果所有语句都成功执行,则提交事务。 总之,使用`tornado_mysql`的连接池和事务非常简单,只需要在您的代码一些额外的异步语句即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值