MySQL ROLLBACK实际上没有回滚(MySQL ROLLBACK not actually rolling back)
我有以下PHP代码:
$dbh->beginTransaction(); $dbh->exec("LOCK TABLES `reservations` WRITE, `settings` WRITE"); $dbh->exec("CREATE TEMPORARY TABLE temp_reservations SELECT * FROM reservations"); $dbh->exec("ALTER TABLE `temp_reservations` ADD INDEX ( conf_num ) ; "); // [...Other stuff here with temp_reservations...] $dbh->exec("DELETE QUICK FROM `reservations`"); $dbh->exec("OPTIMIZE TABLE `reservations`"); $dbh->exec("INSERT INTO `reservations` SELECT * FROM temp_reservations"); var_dump(GlobalContainer::$dbh->inTransaction()); // true $dbh->exec("UNLOCK TABLES"); $dbh->rollBack();
事务对于定期更新/插入工作正常,但上述代码由于某种原因不适用。 当上面发生错误时,我留下了一个完全空的
reservations
表。 我在PDO :: beginTransaction页面上读到,“ 当在事务中发出数据库定义语言(DDL)语句(如DROP TABLE或CREATE TABLE)时,某些数据库(包括MySQL)会自动发出隐式COMMIT ”。 MySQL手册有一个“数据定义语句”列表,我假设它与上面列出的DDL相同,后者列出了CREATE TABLE
但我只创建了一个临时表。 有没有办法解决?另外,我留下一个空的
reservations
表这一事实是否表明在DELETE QUICK FROM reservations
查询后发生了提交?编辑 :另外注意,
INSERT INTO reservations
行也会产生以下错误:当其他未缓冲的查询处于活动状态时,无法执行查询。 考虑使用PDOStatement :: fetchAll()。 或者,如果您的代码只是针对mysql运行,则可以通过设置PDO :: MYSQL_ATTR_USE_BUFFERED_QUERY属性来启用查询缓冲。
我试过做
$dbh->setAttribute( PDO::MYSQL_ATTR_USE_BUFFERED_QUERY , true);
但这似乎并没有影响它。 我假设它与交易有关,但我不确定。 任何人都可以找出导致此错误的确切原因吗?I have the following PHP code:
$dbh->beginTransaction(); $dbh->exec("LOCK TABLES `reservations` WRITE, `settings` WRITE"); $dbh->exec("CREATE TEMPORARY TABLE temp_reservations SELECT * FROM reservations"); $dbh->exec("ALTER TABLE `temp_reservations` ADD INDEX ( conf_num ) ; "); // [...Other stuff here with temp_reservations...] $dbh->exec("DELETE QUICK FROM `reservations`"); $dbh->exec("OPTIMIZE TABLE `reservations`"); $dbh->exec("INSERT INTO `reservations` SELECT * FROM temp_reservations"); var_dump(GlobalContainer::$dbh->inTransaction()); // true $dbh->exec("UNLOCK TABLES"); $dbh->rollBack();
Transactions are working fine for regular updates/inserts but the above code for some reason is not. When an error happens above, I'm left with a completely empty
reservations
table. I read on the PDO::beginTransaction page that "some databases, including MySQL, automatically issue an implicit COMMIT when a database definition language (DDL) statement such as DROP TABLE or CREATE TABLE is issued within a transaction". The MySQL manual has a list of "Data Definition Statements", which I would assume is the same as DDL mentioned above which listsCREATE TABLE
but I am only creating a temporary table. Is there any way around this?Also, does the fact that I'm left with an empty
reservations
table show that a commit occurred after theDELETE QUICK FROM reservations
query?Edit: On an additional note, the
INSERT INTO reservations
line also produces the following error:Cannot execute queries while other unbuffered queries are active. Consider using PDOStatement::fetchAll(). Alternatively, if your code is only ever going to run against mysql, you may enable query buffering by setting the PDO::MYSQL_ATTR_USE_BUFFERED_QUERY attribute.
I tried doing
$dbh->setAttribute( PDO::MYSQL_ATTR_USE_BUFFERED_QUERY , true);
but this doesn't seem to affect it. I'm assuming it would have something to do with the transaction, but I'm not sure. Can anyone pinpoint what exactly is causing this error as well?
原文:https://stackoverflow.com/questions/14574037
最满意答案
您可以选择与
DJANGO_SETTINGS_MODULE
一起使用的settings.py文件; 你可以从主要的那个导入*,然后改变需要改变的东西。或者,settings.py只是一个Python文件。 如果需要,您可以从环境变量中获取设置值:
import os ALLOW_ROBOTS = bool(os.getenv('ALLOW_ROBOTS', False))
然后从Travis更改该环境变量。
You can choose which settings.py file to use with
DJANGO_SETTINGS_MODULE
; you can have many that import * from a main one, and then change what needs to be changed.Alternatively, settings.py is just a Python file. You can get values of settings from environment variables, if you want:
import os ALLOW_ROBOTS = bool(os.getenv('ALLOW_ROBOTS', False))
And then change that environment variable from Travis.
相关问答
更多-
django save(commit = False)vs设置初始值(django save(commit = False) vs setting initial value)[2022-01-26]
您的原始表单是未绑定的,这就是为什么当您尝试保存它时,它不会验证,因为字段为空。 你应该使用: form = RecipieForm(request.POST) 这将从填写的值填充表单,然后您可以正常进行。 Your original form is unbound, which is why when you try to save it, it doesn't validate since the fields are empty. You should use: form = RecipieForm ... -
Django设置默认表单值(Django set default form values)[2022-06-25]
您可以使用这里说明的初始化 调用表单构造函数时,有两个选项填充值: form = JournalForm(initial={'tank': 123}) 或者在表单定义中设置值: tank = forms.IntegerField(widget=forms.HiddenInput(), initial=123) You can use initial which is explained here You have two options either populate the value when c ... -
MySQL支持很容易添加。 在您的DATABASES字典中,您将有一个这样的条目: DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'DB_NAME', 'USER': 'DB_USER', 'PASSWORD': 'DB_PASSWORD', 'HOST': 'localhost', # Or an IP Addre ...
-
您需要将players字段的initial属性设置为相关MyUser ID的列表。 快速执行此操作的方法是使用ModelMultipleChoiceField的initial关键字参数: players = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple, queryset=OPTIONS, ...
-
您可以选择与DJANGO_SETTINGS_MODULE一起使用的settings.py文件; 你可以从主要的那个导入*,然后改变需要改变的东西。 或者,settings.py只是一个Python文件。 如果需要,您可以从环境变量中获取设置值: import os ALLOW_ROBOTS = bool(os.getenv('ALLOW_ROBOTS', False)) 然后从Travis更改该环境变量。 You can choose which settings.py file to use with ...
-
稍微hackish: class DynamicWrapper(object): _initialized = False def __init__(self, wrapped_name) self._wrapped = wrapped_name def __get__(self): if not self._initialized: self._initialized = True return s ...
-
我不是django用户,但我认为你正在寻找的postgresql命令是: ALTER SEQUENCE big_integer_seq RESTART 100000000; 最好阅读django / postgresql的文档。 I'm not a django user but I think the postgresql command you are looking for is: ALTER SEQUENCE big_integer_seq RESTART 100000000; Best to re ...
-
原因与任何产品中缺少任何功能的原因相同 - 没有人实现过它。 我猜想on_update比on_delete更不常用,因为使用自动增量id作为主键很受欢迎,这通常不需要更新。 所以on_update的功能没有实现。 Django跟踪器中有一些功能请求: https://code.djangoproject.com/ticket/21265 (关闭wontfix) https://code.djangoproject.com/ticket/21295 (接受补丁) 我不知道补丁是否已集成到任何Django版本中 ...
-
您可以使用文件字段的url属性。 例如,如果你的模型中有FileField“audio”,你可以试试这个来获取文件的url: {{ props.audio.url }} 但是如果你没有模型并且在你的视图中有一些变量包含文件的url'props.audio'你可以将它从视图传递给模板: def my_view(request): return render(request, 'template.html', {'props_url': props.audio}) 现在在模板中获取url简单做以下操 ...
-
如果我理解您的问题,您可能希望在模板中显示:
{% for field in form %}
对 ...{{ field.label_tag }} {{ field.value }}