Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在SQLite中,您究竟是如何处理事务的?_Sql_Sqlite_Transactions - Fatal编程技术网

在SQLite中,您究竟是如何处理事务的?

在SQLite中,您究竟是如何处理事务的?,sql,sqlite,transactions,Sql,Sqlite,Transactions,我试图弄清楚如何在SQLite中进行事务,但我遇到了麻烦。假设我想从一个人的账户转到另一个人的账户。看看下面的代码。评论很多 DROP TABLE IF EXISTS accounts; CREATE TABLE IF NOT EXISTS accounts ( name VARCHAR(20) NOT NULL, balance INTEGER NULL -- Money is going to be stored in cents ); I

我试图弄清楚如何在SQLite中进行事务,但我遇到了麻烦。假设我想从一个人的账户转到另一个人的账户。看看下面的代码。评论很多

DROP TABLE IF EXISTS accounts;
CREATE TABLE IF NOT EXISTS accounts (
    name       VARCHAR(20) NOT NULL,
    balance    INTEGER         NULL -- Money is going to be stored in cents
);

INSERT INTO accounts (name, balance) VALUES
("John Doe",  10050), -- This means 100 dollars and 50 cents
                      -- because 100 dollars and 50 cents is
                      -- 100 * 100 cents + 50 cents = 10050 cents
("Bob Smith", 20000); -- 200 dollars



DROP VIEW IF EXISTS view_accounts;
CREATE VIEW view_accounts AS
    SELECT rowid,
           name,
           printf("$%.2f", balance / 100.0) AS balance
    FROM accounts;

SELECT * FROM view_accounts;
-- rowid       name        balance
-- ----------  ----------  ----------
-- 1           John Doe    $100.50
-- 2           Bob Smith   $200.00



BEGIN TRANSACTION;

-- Subtract $50 from John Doe's balance
UPDATE accounts SET balance = balance - 5000 WHERE rowid = 1;
-- And add $50 to Bob Smith's balance, but let's now intentionally
-- create something erroneous here. Let's say there's been a mistake
-- and we got the wrong rowid (maybe we received an id that does not
-- exist in our table from a host language such as PHP, but really it
-- could be anything from power-down to inadvertent reboot. I'm using
-- this particular example because it's easy to emulate an exceptional
-- situation). Instead of rowid 2, we mistakenly used a rowid of 3
-- which does not exist in our table.
UPDATE accounts SET balance = balance + 5000 WHERE rowid = 3;

-- Here's where I get stuck. What exactly should my next steps be?
-- What statements should I use here? Obviously I should roll all the
-- changes made so far back with the ROLLBACK command if something
-- exceptional happens, but I can't know that beforehand because the
-- value for rowid is received from external sources. On the other hand,
-- I can't use COMMIT either because what if in fact something
-- exceptional did happen? I somehow need to detect that something bad
-- has happened and conditionally either roll all the changes back or, if
-- everything is okay, commit them.

您不能仅在SQLite中执行此操作,因为SQLite没有任何流控制语句

您要查找的与以下伪代码类似:

IF rows-affected = 0 THEN ROLLBACK TRANSACTION
用您想要的任何类型的错误响应替换
回滚事务

由于SQLite语法中没有
IF
语句或类似语句,因此如果没有使用SQLite的代码/编程语言/运行时的帮助,就无法实现这一点

换句话说,最终调用SQLite的编程语言需要查看SQLite引擎报告的受影响的行数,并处理零


请注意,您希望回滚事务这一事实是错误响应的一部分,但此问题与事务本身无关。基本上,您的问题是关于流控制的。

您描述的错误似乎是您的业务逻辑中的一个问题,因此可能应该由PHP脚本来纠正它。如果您的应用程序层可以检测到此错误,您可以使用
回滚
来反转事务中的更改。因此,您的意思是,我必须从主机语言检查是否存在问题,并决定提交更改或通过向SQLite环境发送提交和回滚来回滚更改?正确,SQLite中没有语法可以为您做到这一点。但是我如何知道我的第二条SQL UPDATE语句有问题呢?SQLite在事务模式下不会真正显示错误。运行时中用于调用SQLite的代码应该支持检查受执行语句影响的行数。因此,基本上我需要使用“从帐户中选择更改()”在每个UPDATE语句之后,查看有多少行受到影响。如果零行受到影响,这意味着发生了错误,我需要将所有内容回滚到原来的状态?