我们正在使用SQLAlchemy声明基础,我有一个方法,我想隔离事务级别.为了解释,有两个进程同时写入数据库,我必须让它们在事务中执行它们的逻辑.默认事务隔离级别是READ COMMITTED,但我需要能够使用SERIALIZABLE隔离级别执行一段代码.
这是如何使用SQLAlchemy完成的?现在,我基本上在我们的模型中有一个方法,它继承自SQLAlchemy的声明性基础,基本上需要以事务方式调用.
from psycopg2.extensions import ISOLATION_LEVEL_AUTOCOMMIT
from psycopg2.extensions import ISOLATION_LEVEL_READ_COMMITTED
from psycopg2.extensions import ISOLATION_LEVEL_SERIALIZABLE
class OurClass(SQLAlchemyBaseModel):
@classmethod
def set_isolation_level(cls, level=ISOLATION_LEVEL_SERIALIZABLE):
cls.get_engine().connect().connection.set_isolation_level(level)
@classmethod
def find_or_create(cls, **kwargs):
try:
return cls.query().filter_by(**kwargs).one()
except NoResultFound:
x = cls(**kwargs)
x.save()
return x
Run Code Online (Sandbox Code Playgroud)
我这样做是为了使用事务隔离级别来调用它,但它没有按照我的预期进行.隔离级别仍然是我在postgres日志中看到的READ COMMITTED.有人可以帮助确定我做错了什么吗?
我正在使用SQLAlchemy 0.5.5
class Foo(OurClass):
def insert_this(self, kwarg1=value1):
# I am trying to set the isolation level to SERIALIZABLE
try:
self.set_isolation_level()
with Session.begin():
self.find_or_create(kwarg1=value1)
except Exception: # if any exception is thrown...
print "I caught an expection."
print sys.exc_info()
finally:
# Make …Run Code Online (Sandbox Code Playgroud) 我有一个函数,它在同一个数据集上执行多个查询,我想确保所有查询都能看到完全相同的数据.
就SQL而言,这意味着支持它的数据库的REPEATABLE READ隔离级别.如果数据库不具备,我不介意更高级别甚至完全锁定.
据我所知,情况并非如此.即如果我在一个Python shell中运行类似这样的代码:
with transaction.atomic():
for t in range(0, 60):
print("{0}: {1}".format(t, MyModel.objects.count()))
time.sleep(1)
Run Code Online (Sandbox Code Playgroud)
一旦我MyModel.objects.create(...)在另一个中,运行循环看到的值立即增加.这正是我想要避免的.进一步的测试显示行为符合READ COMMITTED级别,这对我的口味来说太宽松了.
我还想强调一点,我想要更严格的隔离级别只针对单个函数,而不是整个项目.
我最好的选择是什么?
在我的特殊情况下,我唯一关心的数据库是PostgreSQL 9.3+,但我也希望与SQLite3有一些兼容性,在这种情况下即使完全锁定整个数据库也没关系.然而,显然,解决方案越普遍,它就越优选.
python django transactions transaction-isolation isolation-level
我正在编写一些将在生产中运行的日志/审计代码(不仅仅是在抛出错误或开发时).在阅读了Coding Horror的死锁和伐木经验后,我决定寻求建议.(杰夫的"不记录"解决方案对我不起作用,这是法律规定的安全审计)
是否有合适的隔离级别可以最大限度地减少争用和死锁?我可以添加到insert语句或存储过程的任何查询提示?
我非常关心除审计表之外的所有事务的事务完整性.我的想法是记录如此多,如果一些条目失败,这不是问题.如果日志记录停止了某个其他事务 - 那将是不好的.
我可以登录到数据库或文件,虽然登录到文件不那么有吸引力,因为我需要能够以某种方式显示结果.记录到文件会(几乎)保证日志记录不会干扰其他代码.
我正在尝试使用不正确的IsolationLevels来处理我们的应用程序中是否存在数据库连接问题.我们的应用程序是使用SQL Server 2005的.Net 3.5数据库应用程序.
我发现连接的IsolationLevel在返回到连接池时没有被重置(参见这里),并且在这篇博文中读到每个新创建的TransactionScope都有自己的连接池分配给它时也很惊讶.
我们的数据库更新(通过我们的业务对象)在TransactionScope中进行(为每个业务对象图更新创建一个新的).但我们的提取不使用显式事务.所以我想知道的是,我们是否可能遇到这样的情况:我们的获取操作(应使用默认的IsolationLevel - Read Committed)将重用已用于更新的池中的连接,并继承更新IsolationLevel (REPEATABLEREAD)?或者我们的更新是否会保证使用不同的连接池,因为它们包含在TransactionScope中?
提前致谢,
格雷厄姆
sql-server connection-pooling transactionscope isolation-level .net-3.5
我在我的项目基于注释的事务管理中使用(我使用@Transactional注释一些方法).我想全局设置隔离级别(而不是将其作为每个@Transactional注释的参数).
是否有可能在XML中配置?目前我的xml配置包含
<tx:annotation-driven transaction-manager="txManager"/>
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
Run Code Online (Sandbox Code Playgroud)
是否有可能以某种方式将隔离添加到tx:annotation-driven?
我研究过的文档表明,为其他数据库执行此操作的方法是在查询中使用多个语句,a:
>>> cursor = connection.cursor()
>>> cursor.execute("set session transaction isolation level read uncommitted;
select stuff from table;
set session transaction isolation level repeatable read;")
Run Code Online (Sandbox Code Playgroud)
不幸的是,这样做没有结果,因为显然Python DB API(或者只是它的实现?)不支持单个查询中的多个记录集.
过去有没有其他人成功?
启用了InnoDB插件的MySQL Server版本5.1.41.我有以下三张发票表:发票,invoice_components和invoice_expenses.表发票具有invoice_id主键.invoice_components和invoice_expenses都链接到表发票,其invoice_id为非唯一foreign_key(每张发票可以包含多个组件和多个费用).两个表都具有此外键的BTREE索引.
我有以下交易:
交易1
START TRANSACTION;
SELECT * FROM invoices WHERE invoice_id = 18 FOR UPDATE;
SELECT * FROM invoice_components WHERE invoice = 18 FOR UPDATE;
SELECT * FROM invoice_expenses WHERE invoice = 18 FOR UPDATE;
Run Code Online (Sandbox Code Playgroud)
对于第一个事务,一切正常,并且选择并锁定行.
交易2
START TRANSACTION;
SELECT * FROM invoices WHERE invoice_id = 19 FOR UPDATE;
SELECT * FROM invoice_components WHERE invoice = 19 FOR UPDATE;
SELECT * FROM invoice_expenses WHERE invoice = 19 FOR UPDATE;
Run Code Online (Sandbox Code Playgroud)
第二个事务返回ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting …
我尝试使用MySQL Server 5.5:
1)确保事务隔离级别是repeatable_read
2)启动shell-1,在其中启动一个事务,然后通过select读取一个值
3)启动shell-2,在其中启动一个事务,然后通过select读取相同的值
4)在shell-1中,将值更新为值+ 1并提交
5)在shell-2中,将值更新为值+ 1并提交
该值丢失了其中一个更新,并且仅增加1.
现在,据我所知,RR使用共享读锁和独占写锁,这意味着在上面的#4和#5中,事务应该已经死锁,但是没有发生.
所以要么我对RR的理解有问题,要么MySQL以不同的方式实现RR.那是什么?
编辑:通过类似的实验,还确认RR事务(t1)没有看到行被另一个RR事务(t2)插入到同一个表中,如果它在该表上做了另一个选择,即使在t2提交之后和t1提交之前.(以下是此实验的链接:http://www.databasejournal.com/features/mysql/article.php/3393161/MySQL-Transactions-Part-II---Transaction-Isolation-Levels.htm)
这是否意味着MySQL的RR还会处理幻像读取?
我正在研究DW项目,我需要查询实时CRM系统.标准隔离级别会对性能产生负面影响.我很想使用没有锁定/事务隔离级别读取未提交.我想知道脏读的标识有多少选定的行.
我正在执行几个长时间运行的SQL查询作为报告模块的一部分.这些查询是在运行时动态构造的.根据用户的输入,它们可以是单个或多个语句,具有一个或多个参数并在一个或多个数据库表上运行 - 换句话说,它们的形式不容易预料到.
目前,我只是在普通的情况下执行这些陈述SqlConnection,即
using (SqlConnection cn = new SqlConnection(ConnectionString)) {
cn.Open();
// command 1
// command 2
// ...
// command N
}
Run Code Online (Sandbox Code Playgroud)
因为这些查询(实际上是查询批处理)可能需要一段时间才能执行,所以我担心会阻塞其他用户的读/写表.如果这些报告的数据在批处理执行期间发生变化,则不会出现问题.报表查询永远不应优先于这些表上的其他操作,也不应锁定它们.
对于涉及修改数据的大多数长时间运行/多语句操作,我会使用事务.这里的区别在于这些报告查询不会修改任何数据.我是否可以正确地将这些报告查询包装起来SqlTransaction以控制它们的隔离级别?
即:
using (SqlConnection cn = new SqlConnection(ConnectionString)) {
cn.Open();
using (SqlTransaction tr = cn.BeginTransaction(IsolationLevel.ReadUncommitted)) {
// command 1
// command 2
// ...
// command N
tr.Commit();
}
}
Run Code Online (Sandbox Code Playgroud)
这会实现我想要的结果吗?提交事务是否正确,即使没有修改数据?还有另一种方法吗?
isolation-level ×10
transactions ×5
sql-server ×4
mysql ×3
python ×3
.net-3.5 ×1
ado.net ×1
audit-tables ×1
c# ×1
deadlock ×1
django ×1
innodb ×1
locks ×1
logging ×1
postgresql ×1
spring ×1
sql ×1
sqlalchemy ×1
t-sql ×1